Giter Site home page Giter Site logo

automapper.data's Introduction

AutoMapper

CI NuGet MyGet (dev) Documentation Status

What is AutoMapper?

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?

This is the main repository for AutoMapper, but there's more:

How do I get started?

First, configure AutoMapper to know what types you want to map, in the startup of your application:

var configuration = new MapperConfiguration(cfg => 
{
    cfg.CreateMap<Foo, FooDto>();
    cfg.CreateMap<Bar, BarDto>();
});
// only during development, validate your mappings; remove it before release
#if DEBUG
configuration.AssertConfigurationIsValid();
#endif
// use DI (http://docs.automapper.org/en/latest/Dependency-injection.html) or create the mapper yourself
var mapper = configuration.CreateMapper();

Then in your application code, execute the mappings:

var fooDto = mapper.Map<FooDto>(foo);
var barDto = mapper.Map<BarDto>(bar);

Check out the getting started guide. When you're done there, the wiki goes in to the nitty-gritty details. If you have questions, you can post them to Stack Overflow or in our Gitter.

Where can I get it?

First, install NuGet. Then, install AutoMapper from the package manager console:

PM> Install-Package AutoMapper

Or from the .NET CLI as:

dotnet add package AutoMapper

Do you have an issue?

First check if it's already fixed by trying the MyGet build.

You might want to know exactly what your mapping does at runtime.

If you're still running into problems, file an issue above.

License, etc.

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the .NET Foundation Code of Conduct.

AutoMapper is Copyright © 2009 Jimmy Bogard and other contributors under the MIT license.

.NET Foundation

This project is supported by the .NET Foundation.

automapper.data's People

Contributors

colonelduddits avatar jbogard avatar jhamm avatar lbargaoanu avatar mettolen avatar pierta avatar ran-snow avatar say25 avatar svencal avatar tek-ncalinoi avatar watercable76 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

automapper.data's Issues

Please provide PDBs

I just started using AutoMapper.Data and I am trying to figure out how to map IDataReader to arbitrary Ts dynamically/at runtime.

The exceptions I receive are often very cryptic and it would help a lot, if there was a symbol package (snupkg) or similar available. It would make debugging these exceptions a lot easier and help me figure out what AutoMapper is expecting.

Thank you!

AddDataReaderMapping not ignoring recursive class property

Hi,

I'm getting an error when setting up MapperConfiguration with AddDataReaderMapping() for a class that has self reference:

Configuration:

var config = new MapperConfiguration(cfg =>
 {
                cfg.AddDataReaderMapping();
                cfg.CreateMap<IDataReader, SimpleNode>()
                   .ForMember(sn => sn.Parent, opt => { opt.Ignore();});
 });

The class:

    public class SimpleNode
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public SimpleNode Parent { get; set; }
        public IEnumerable<SimpleNode> Children { get; set; }
    }

The error:

System.InvalidOperationException
HResult=0x80131509
Message=Opcodes using a short-form index cannot address a local position over 255.
Source=System.Private.CoreLib
StackTrace:
at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, LocalBuilder local)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, List1 resolvers, IMemberConfiguration parent, Boolean isReverseMap) at AutoMapper.Configuration.Conventions.MemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, List1 resolvers, Boolean isReverseMap)
at AutoMapper.ProfileMap.MapDestinationPropertyToSource(TypeDetails sourceTypeDetails, Type destType, Type destMemberType, String destMemberName, List1 members, Boolean reverseNamingConventions) at AutoMapper.TypeMap..ctor(Type sourceType, Type destinationType, ProfileMap profile, Boolean isReverseMap) at AutoMapper.ProfileMap.BuildTypeMap(IGlobalConfiguration configurationProvider, ITypeMapConfiguration config) at AutoMapper.ProfileMap.Register(IGlobalConfiguration configurationProvider) at AutoMapper.MapperConfiguration.Seal() at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression) at AutoMapper.MapperConfiguration..ctor(Action1 configure)

Note that I do not need to map the Parent (this is done manually). I just want to ignore that field.
Automapper version: 11.0.1
Automapper.Data version: 6.0.0

Thank you for any help!
Rokas

Not mapping records

Mapping to a class works as expected. E.g.:

public class Test
{
    public string? Name { get; set; }
};

Mapping to this record does not work.

public record Test
{
    public string? Name { get; set; }
};

Error:

System.NullReferenceException
  Message = Object reference not set to an instance of an object.

at

_mapper.Map<IDataReader, List<Test>>(reader);

Mapping to this record gives a different error:

public record Test(string Name);

Error:

Destination Member:
Application.Common.Interfaces.Test.Void .ctor(System.String).parameter Name
 ---> System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Reflection.RuntimeParameterInfo'.
   at GetName(IDataRecord )
   at lambda_method27(Closure , IDataReader , List`1 , ResolutionContext )
   --- End of inner exception stack trace ---
   at lambda_method27(Closure , IDataReader , List`1 , ResolutionContext )
   --- End of inner exception stack trace ---
   at lambda_method27(Closure , IDataReader , List`1 , ResolutionContext )

I am using AutoMapper.Extensions.Microsoft.DependencyInjection 8.1.1 and AutoMapper.Data 5.0.0. With AutoMapper.Extensions.Microsoft.DependencyInjection on its own, mapping to records works perfectly.

Map<IDataReader, MyType>(sourceReader, destinationObject) not updating destinationObject

destinationObject = Map<IDataReader, MyType>(sourceReader) does work.

From the DataReaderMapping unit test, change the Establish_context method (the Mapper.Map line)

        protected override void Establish_context()
        {
            Mapper.CreateMap<IDataRecord, DTOObject>()
                .ForMember(dest => dest.Else, options => options.MapFrom(src => src.GetDateTime(src.GetOrdinal(FieldName.Something))));

            _dataRecord = new DataBuilder().BuildDataRecord();
            var result = new DTOObject();
            Mapper.Map<IDataRecord, DTOObject>(_dataRecord, result);
            _result = result;
        }

I've tracked it down to the MapPropertyValues method in DataReaderMapper.cs.

The context.TypeMap.GetPropertyMaps() does not have property maps for any properties other than the 'Else' defined in the ForMember extension in the unit test.

I've tried using ForAllMembers to 'trick' the property maps into adding the missing properties, but there are no _sourceValueResolvers for these property maps.

Suggestions on how to address?

IDataReader mapping to Class with matching names, but different IDataReader contracts

From @philai on May 7, 2013 15:17

I have a very simple object:
public class EntityIsInUse
{
public EntityIsInUse()
{
// Default to True as the ByID stored procedures do NOT return this information.
IsActive = true;
}

    public TableName InUseByTableName { get; set; }
    public long EntityID { get; set; }
    public bool IsActive { get; set; }
    public bool IsInUse { get; set; }
}

And a number of different stored procedures that return the following columns:
TableName, EntityID, IsActive, IsInUse

However, EntityID can be TINYINT, SMALLINT or INT
And IsInUse can be a result from a COUNT function or a BIT
SELECT
'Environment' AS TableName
, EnvironmentID AS EntityID
, IsActive
, IsActive AS IsInUse
FROM
dbo.Environment (NOLOCK)

AutoMapper is caching the first mapping I do so subsequent maps fail because of a mismatch in contracts when using the following:
Mapper.CreateMap<IDataReader, EntityIsInUse>()
.ForMember(m => m.InUseByTableName, o => o.MapFrom(s => s["TableName"].ToString().ParseEnum(true)));

In order to prevent this, I've had to rename the EntityID and IsInUse properties of my class so they do NOT match the field names returned by my stored procedures:
Mapper.CreateMap<IDataReader, EntityIsInUse>()
.ForMember(m => m.InUseByTableName, o => o.MapFrom(s => s["TableName"].ToString().ParseEnum(true)))
.ForMember(m => m.EntityIDAsLong, o => o.MapFrom(s => Convert.ToInt64(s["EntityID"])))
.ForMember(m => m.IsInUseAsBoolean, o => o.MapFrom(s => s["IsInUse"].ParseBool()));

Is this a bug? Or is my solution actually the only way to resolve this?

Copied from original issue: AutoMapper/AutoMapper#333

ExecutionEngineException thrown when mapping with IDataReader to DTO with a different datatype for a property

From @janv8000 on November 19, 2012 8:29

An ExecutionEngineException without any useful debug information is thrown when executing the following code. This only happens with a Release build without a debugger attached. When debugging the data comes out just fine.

Versions used:
Automapper NuGet version 2.2.0
.NET 4

Database schema:

CREATE TABLE [dbo].[Foo](
[Bar] [numeric](4, 0) NOT NULL,
[Baz] [nvarchar](50) NOT NULL
)

INSERT [dbo].[Foo] ([Bar], [Baz]) VALUES (CAST(0 AS Numeric(4, 0)), N'0')
INSERT [dbo].[Foo] ([Bar], [Baz]) VALUES (CAST(112 AS Numeric(4, 0)), N'112')

Code:

class Program
{
    public class Foo
    {
        public int Bar { get; set; }
        public string Baz { get; set; }
    }

    static void Main(string[] args)
    {
        //Build as release and X86 or Any CPU
        var stringBuilder = new StringBuilder();
        stringBuilder.Append("SELECT Bar , ");// Bar is actually a numeric(4,0) but declared in dto as int
        stringBuilder.Append("       Baz ");
        stringBuilder.Append("FROM   Foo");

        List<Foo> result;
        using (var connection = new SqlConnection("Server=localsqlalias;Database=AutoMapperTest;Integrated Security=True;"))
        {
            connection.Open();
            using (var sqlCommand = new SqlCommand(stringBuilder.ToString(), connection))
            {
                using (var sqlDataReader = sqlCommand.ExecuteReader())
                {
                    Mapper.CreateMap<IDataReader, IEnumerable<Foo>>();
                    result = Mapper.Map<IDataReader, IEnumerable<Foo>>((IDataReader)sqlDataReader).ToList();
                }
            }
        }

        foreach (var aResult in result)
        {
            Console.WriteLine("{0} {1}", aResult.Bar, aResult.Baz);
        }

        Console.WriteLine("Press enter to quit");
        Console.ReadLine();
    }
}

Copied from original issue: AutoMapper/AutoMapper#273

Mapper not working with DI, AM 6.2.1 AM.D 1.0.1

EDIT
Hi, sorry for my bad English. I'm investigating a strange problem with the above component combination. The DI container is Castle Windsor v4.1.0.

From the project:

namespace AutoMapper.Data.Tests
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Installer;
using Configuration.Conventions;
using Mappers;
using Shouldly;
using Xunit;

public class MyProfileInitializer : Profile
{
    public MyProfileInitializer()
    {
        CreateMap<IDataRecord, DTOObject>();
        Debug.WriteLine("MyProfile initialized");
    }
}

public class When_mapping_a_data_reader_to_a_dto_via_castle
{
    private WindsorContainer Container;

    public When_mapping_a_data_reader_to_a_dto_via_castle()
    {

        Container = new WindsorContainer();
        Container.AddFacility<TypedFactoryFacility>();
        Container.Install(FromAssembly.InThisApplication(Assembly.GetExecutingAssembly()));
        Container.Register(Types.FromAssemblyInThisApplication(Assembly.GetExecutingAssembly())
            .BasedOn<Profile>()
            .WithServiceBase()
            .Unless(type => !type.Name.EndsWith("Initializer"))
            .Configure(c => c.Named(c.Implementation.FullName))
            .LifestyleTransient());
        Mapper.Initialize(cfg => {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            Container.ResolveAll<Profile>().ToList().ForEach(cfg.AddProfile);
        });

        // Register to inject static instance
        Container.Register(Component.For<IMapper>().Instance(Mapper.Instance));

        IMapper mapper = Container.Resolve<IMapper>();
        DataReader = new DataBuilder().BuildDataReader();
        Results = mapper.Map<IDataReader, IEnumerable<DTOObject>>(DataReader);
        Result = Results.FirstOrDefault();
    }

    ~When_mapping_a_data_reader_to_a_dto_via_castle()
    {
        Container.Dispose();
    }

    [Fact]
    public void Then_a_column_containing_a_small_integer_should_be_read()
    {
        Result.SmallInteger.ShouldBe(DataReader[FieldName.SmallInt]);
    }

    [Fact]
    public void Then_a_column_containing_an_integer_should_be_read()
    {
        Result.Integer.ShouldBe(DataReader[FieldName.Int]);
    }

    [Fact]
    public void Then_a_column_containing_a_big_integer_should_be_read()
    {
        Result.BigInteger.ShouldBe(DataReader[FieldName.BigInt]);
    }

    [Fact]
    public void Then_a_column_containing_a_GUID_should_be_read()
    {
        Result.Guid.ShouldBe(DataReader[FieldName.Guid]);
    }

    [Fact]
    public void Then_a_column_containing_a_float_should_be_read()
    {
        Result.Float.ShouldBe(DataReader[FieldName.Float]);
    }

    [Fact]
    public void Then_a_column_containing_a_double_should_be_read()
    {
        Result.Double.ShouldBe(DataReader[FieldName.Double]);
    }

    [Fact]
    public void Then_a_column_containing_a_decimal_should_be_read()
    {
        Result.Decimal.ShouldBe(DataReader[FieldName.Decimal]);
    }

    [Fact]
    public void Then_a_column_containing_a_date_and_time_should_be_read()
    {
        Result.DateTime.ShouldBe(DataReader[FieldName.DateTime]);
    }

    [Fact]
    public void Then_a_column_containing_a_byte_should_be_read()
    {
        Result.Byte.ShouldBe(DataReader[FieldName.Byte]);
    }

    [Fact]
    public void Then_a_column_containing_a_boolean_should_be_read()
    {
        Result.Boolean.ShouldBe(DataReader[FieldName.Boolean]);
    }

    [Fact]
    public void Then_a_projected_column_should_be_read()
    {
        Result.Else.ShouldBe(DataReader.GetDateTime(10));
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }

    protected virtual bool YieldReturnEnabled => false;
    protected DTOObject Result { get; set; }
    protected IEnumerable<DTOObject> Results { get; set; }
    protected IDataReader DataReader { get; set; }
}

public class When_mapping_a_data_reader_to_a_dto
{
    public When_mapping_a_data_reader_to_a_dto()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddDataReaderMapping(YieldReturnEnabled);

            cfg.CreateMap<IDataRecord, DTOObject>()
                .ForMember(dest => dest.Else, options => options.MapFrom(src => src.GetDateTime(10)));
        });

        DataReader = new DataBuilder().BuildDataReader();
        Results = Mapper.Map<IDataReader, IEnumerable<DTOObject>>(DataReader);
        Result = Results.FirstOrDefault();
    }

    [Fact]
    public void Then_a_column_containing_a_small_integer_should_be_read()
    {
        Result.SmallInteger.ShouldBe(DataReader[FieldName.SmallInt]);
    }

    [Fact]
    public void Then_a_column_containing_an_integer_should_be_read()
    {
        Result.Integer.ShouldBe(DataReader[FieldName.Int]);
    }

    [Fact]
    public void Then_a_column_containing_a_big_integer_should_be_read()
    {
        Result.BigInteger.ShouldBe(DataReader[FieldName.BigInt]);
    }

    [Fact]
    public void Then_a_column_containing_a_GUID_should_be_read()
    {
        Result.Guid.ShouldBe(DataReader[FieldName.Guid]);
    }

    [Fact]
    public void Then_a_column_containing_a_float_should_be_read()
    {
        Result.Float.ShouldBe(DataReader[FieldName.Float]);
    }

    [Fact]
    public void Then_a_column_containing_a_double_should_be_read()
    {
        Result.Double.ShouldBe(DataReader[FieldName.Double]);
    }

    [Fact]
    public void Then_a_column_containing_a_decimal_should_be_read()
    {
        Result.Decimal.ShouldBe(DataReader[FieldName.Decimal]);
    }

    [Fact]
    public void Then_a_column_containing_a_date_and_time_should_be_read()
    {
        Result.DateTime.ShouldBe(DataReader[FieldName.DateTime]);
    }

    [Fact]
    public void Then_a_column_containing_a_byte_should_be_read()
    {
        Result.Byte.ShouldBe(DataReader[FieldName.Byte]);
    }

    [Fact]
    public void Then_a_column_containing_a_boolean_should_be_read()
    {
        Result.Boolean.ShouldBe(DataReader[FieldName.Boolean]);
    }

    [Fact]
    public void Then_a_projected_column_should_be_read()
    {
        Result.Else.ShouldBe(DataReader.GetDateTime(10));
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }

    protected virtual bool YieldReturnEnabled => false;
    protected DTOObject Result { get; set; }
    protected IEnumerable<DTOObject> Results { get; set; }
    protected IDataReader DataReader { get; set; }
}

public class When_mapping_a_data_reader_to_matching_dtos
{
    public When_mapping_a_data_reader_to_matching_dtos()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            cfg.CreateMap<IDataRecord, DTOObject>()
                .ForMember(dest => dest.Else, options => options.MapFrom(src => src.GetDateTime(10)));
            cfg.CreateMap<IDataRecord, DerivedDTOObject>()
                .ForMember(dest => dest.Else, options => options.MapFrom(src => src.GetDateTime(10)));
        });

        Mapper.Map<IDataReader, IEnumerable<DTOObject>>(new DataBuilder().BuildDataReader()).ToArray();

    }
    [Fact]
    public void Should_map_successfully()
    {
        var result = Mapper.Map<IDataReader, IEnumerable<DerivedDTOObject>>(new DataBuilder().BuildDataReader());
        result.Count().ShouldBe(1);
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }
}
/// <summary>
/// The purpose of this test is to exercise the internal caching logic of DataReaderMapper.
/// </summary>
public class When_mapping_a_data_reader_to_a_dto_twice : When_mapping_a_data_reader_to_a_dto
{
    public When_mapping_a_data_reader_to_a_dto_twice() 
    {
        DataReader = new DataBuilder().BuildDataReader();
        Results = Mapper.Map<IDataReader, IEnumerable<DTOObject>>(DataReader);
        Result = Results.FirstOrDefault();
    }
}

public class When_mapping_a_data_reader_using_the_default_configuration : When_mapping_a_data_reader_to_a_dto
{
    [Fact]
    public void Then_the_enumerable_should_be_a_list()
    {
        Results.ShouldBeAssignableTo<IList<DTOObject>>();
    }
}

public class When_mapping_a_data_reader_using_the_yield_return_option : When_mapping_a_data_reader_to_a_dto
{
    protected override bool YieldReturnEnabled => true;

    [Fact]
    public void Then_the_enumerable_should_not_be_a_list()
    {
        (Results is IList<DTOObject>).ShouldBeFalse();
    }
}

public class When_mapping_a_data_reader_to_a_dto_and_the_map_does_not_exist
{
    public When_mapping_a_data_reader_to_a_dto_and_the_map_does_not_exist()
    {
        Mapper.Initialize(cfg => cfg.Mappers.Insert(0, new DataReaderMapper()));
        _dataReader = new DataBuilder().BuildDataReader();
    }

    [Fact]
    public void Then_an_automapper_exception_should_be_thrown()
    {
        var passed = false;
        try
        {
            Mapper.Map<IDataReader, IEnumerable<DTOObject>>(_dataReader).FirstOrDefault();
        }
        catch (AutoMapperMappingException)
        {
            passed = true;
        }

        passed.ShouldBeTrue();
    }

    private IDataReader _dataReader;
}


public class When_mapping_a_single_data_record_to_a_dto
{
    public When_mapping_a_single_data_record_to_a_dto()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            cfg.CreateMap<IDataRecord, DTOObject>()
                .ForMember(dest => dest.Else, options => options.MapFrom(src => src.GetDateTime(src.GetOrdinal(FieldName.Something))));
        });

        _dataRecord = new DataBuilder().BuildDataRecord();
        _result = Mapper.Map<IDataRecord, DTOObject>(_dataRecord);
    }

    [Fact]
    public void Then_a_column_containing_a_small_integer_should_be_read()
    {
        _result.SmallInteger.ShouldBe(_dataRecord[FieldName.SmallInt]);
    }

    [Fact]
    public void Then_a_column_containing_an_integer_should_be_read()
    {
        _result.Integer.ShouldBe(_dataRecord[FieldName.Int]);
    }

    [Fact]
    public void Then_a_column_containing_a_big_integer_should_be_read()
    {
        _result.BigInteger.ShouldBe(_dataRecord[FieldName.BigInt]);
    }

    [Fact]
    public void Then_a_column_containing_a_GUID_should_be_read()
    {
        _result.Guid.ShouldBe(_dataRecord[FieldName.Guid]);
    }

    [Fact]
    public void Then_a_column_containing_a_float_should_be_read()
    {
        _result.Float.ShouldBe(_dataRecord[FieldName.Float]);
    }

    [Fact]
    public void Then_a_column_containing_a_double_should_be_read()
    {
        _result.Double.ShouldBe(_dataRecord[FieldName.Double]);
    }

    [Fact]
    public void Then_a_column_containing_a_decimal_should_be_read()
    {
        _result.Decimal.ShouldBe(_dataRecord[FieldName.Decimal]);
    }

    [Fact]
    public void Then_a_column_containing_a_date_and_time_should_be_read()
    {
        _result.DateTime.ShouldBe(_dataRecord[FieldName.DateTime]);
    }

    [Fact]
    public void Then_a_column_containing_a_byte_should_be_read()
    {
        _result.Byte.ShouldBe(_dataRecord[FieldName.Byte]);
    }

    [Fact]
    public void Then_a_column_containing_a_boolean_should_be_read()
    {
        _result.Boolean.ShouldBe(_dataRecord[FieldName.Boolean]);
    }

    [Fact]
    public void Then_a_projected_column_should_be_read()
    {
        _result.Else.ShouldBe(_dataRecord[FieldName.Something]);
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }

    private DTOObject _result;
    private IDataRecord _dataRecord;
}

public class When_mapping_a_data_reader_to_a_dto_with_nullable_field
{
    internal const string FieldName = "Integer";
    internal const int FieldValue = 7;

    internal class DtoWithSingleNullableField
    {
        public int? Integer { get; set; }
    }

    internal class DataBuilder
    {
        public IDataReader BuildDataReaderWithNullableField()
        {
            var table = new DataTable();

            var col = table.Columns.Add(FieldName, typeof(int));
            col.AllowDBNull = true;

            var row1 = table.NewRow();
            row1[FieldName] = FieldValue;
            table.Rows.Add(row1);

            var row2 = table.NewRow();
            row2[FieldName] = DBNull.Value;
            table.Rows.Add(row2);

            return table.CreateDataReader();
        }
    }

    public When_mapping_a_data_reader_to_a_dto_with_nullable_field()
    {
        Mapper.Initialize(cfg => {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            cfg.CreateMap<IDataReader, DtoWithSingleNullableField>();
        });

        _dataReader = new DataBuilder().BuildDataReaderWithNullableField();
    }

    [Fact]
    public void Then_results_should_be_as_expected()
    {
        while (_dataReader.Read())
        {
            var dto = Mapper.Map<IDataReader, DtoWithSingleNullableField>(_dataReader);

            if (_dataReader.IsDBNull(0))
                dto.Integer.HasValue.ShouldBe(false);
            else
            {
                // uncomment the following line to see some strange fail message that might be the key to the problem
                dto.Integer.HasValue.ShouldBe(true);

                dto.Integer.Value.ShouldBe(FieldValue);
            }
        }
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }

    private IDataReader _dataReader;
}

public class When_mapping_a_data_reader_to_a_dto_with_nullable_enum
{
    internal const string FieldName = "Value";
    internal const int FieldValue = 3;

    public enum settlement_type
    {
        PreDelivery = 0,
        DVP = 1,
        FreeDelivery = 2,
        Prepayment = 3,
        Allocation = 4,
        SafeSettlement = 5,
    }
    internal class DtoWithSingleNullableField
    {
        public settlement_type? Value { get; set; }
    }

    internal class DataBuilder
    {
        public IDataReader BuildDataReaderWithNullableField()
        {
            var table = new DataTable();

            var col = table.Columns.Add(FieldName, typeof(int));
            col.AllowDBNull = true;

            var row1 = table.NewRow();
            row1[FieldName] = FieldValue;
            table.Rows.Add(row1);

            var row2 = table.NewRow();
            row2[FieldName] = DBNull.Value;
            table.Rows.Add(row2);

            return table.CreateDataReader();
        }
    }

    public When_mapping_a_data_reader_to_a_dto_with_nullable_enum()
    {
        Mapper.Initialize(cfg => {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
        });

        _dataReader = new DataBuilder().BuildDataReaderWithNullableField();
    }

    [Fact]
    public void Then_results_should_be_as_expected()
    {
        while (_dataReader.Read())
        {
            //var dto = Mapper.Map<IDataReader, DtoWithSingleNullableField>(_dataReader);
            var dto = new DtoWithSingleNullableField();

            object value = _dataReader[0];
            if (!Equals(value, DBNull.Value))
                dto.Value = (settlement_type)value;

            if (_dataReader.IsDBNull(0))
                dto.Value.HasValue.ShouldBeFalse();
            else
            {
                dto.Value.HasValue.ShouldBeTrue();

                dto.Value.Value.ShouldBe(settlement_type.Prepayment);
            }
        }
    }

    [Fact]
    public void Should_have_valid_mapping()
    {
        Mapper.AssertConfigurationIsValid();
    }

    private IDataReader _dataReader;
}

public class When_mapping_a_data_reader_to_a_dto_with_nested_dto
{
    internal const string FieldName = "Integer";
    internal const int FieldValue = 7;
    internal const string InnerFieldName = "Inner.Descr";
    internal const string InnerFieldName2 = "Inner.Descr2";
    internal const string Inner2FieldName2 = "Inner2.Descr2";
    internal const string InnerFieldValue = "Hello";
    internal const string InnerFieldValue2 = "World";
    internal const string Inner2FieldValue2 = "2World2";

    internal class DtoInnerClass
    {
        public string Descr { get; set; }
        public string Descr2 { get; set; }
    }

    internal class DtoWithNestedClass
    {
        public int Integer { get; set; }
        public DtoInnerClass Inner { get; set; }
        public DtoInnerClass Inner2 { get; set; }
        public DtoInnerClass Inner3 { get; set; }
    }

    internal class DataBuilder
    {
        public IDataReader BuildDataReaderWithNestedClass()
        {
            var table = new DataTable();

            var col = table.Columns.Add(FieldName, typeof(int));
            col.AllowDBNull = true;
            table.Columns.Add(InnerFieldName, typeof(string));
            table.Columns.Add(InnerFieldName2, typeof(string));
            table.Columns.Add("Inner2.Descr", typeof(string));
            table.Columns.Add(Inner2FieldName2, typeof(string));
            table.Columns.Add("Inner3.Descr", typeof(string));
            table.Columns.Add("Inner3.Descr2", typeof(string));

            var row1 = table.NewRow();
            row1[FieldName] = FieldValue;
            row1[InnerFieldName] = InnerFieldValue;
            row1[InnerFieldName2] = InnerFieldValue2;
            row1["Inner2.Descr"] = null;
            row1[Inner2FieldName2] = Inner2FieldValue2;
            row1["Inner3.Descr"] = null;
            row1["Inner3.Descr2"] = null;
            table.Rows.Add(row1);

            return table.CreateDataReader();
        }
    }

    public When_mapping_a_data_reader_to_a_dto_with_nested_dto()
    {
        Mapper.Initialize(cfg => {
            cfg.Mappers.Insert(0, new DataReaderMapper());
            
            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            cfg.CreateMap<IDataRecord, DtoWithNestedClass>();
        });

        _dataReader = new DataBuilder().BuildDataReaderWithNestedClass();
    }

    [Fact]
    public void Then_results_should_be_as_expected()
    {
        while (_dataReader.Read())
        {
            var dto = Mapper.Map<IDataReader, DtoWithNestedClass>(_dataReader);

            dto.Integer.ShouldBe(FieldValue);

            // nested property
            dto.Inner.ShouldNotBeNull();
            dto.Inner.Descr.ShouldBe(InnerFieldValue);
            dto.Inner.Descr2.ShouldBe(InnerFieldValue2);

            // more than one property
            dto.Inner2.ShouldNotBeNull();
            dto.Inner2.Descr.ShouldBeNull(); // null
            dto.Inner2.Descr2.ShouldBe(Inner2FieldValue2);

            // no Inner3 properties are set so the Inner3 property is null
            dto.Inner3.ShouldBeNull();
        }
    }

    private IDataReader _dataReader;
}

public class When_mapping_a_data_reader_to_a_dto_with_missing_columns_in_data_reader
{
    internal const string FieldName = "Integer";
    internal const int FieldValue = 7;

    internal class DtoWithMoreColumnsThanDataReader
    {
        public int Integer { get; set; }
        public int Integer2 { get; set; }
        public string String1 { get; set; }
    }

    internal class DataBuilder
    {
        public IDataReader BuildDataReaderWithMissingColumns()
        {
            var table = new DataTable();

            var col = table.Columns.Add(FieldName, typeof(int));
            col.AllowDBNull = true;

            var row1 = table.NewRow();
            row1[FieldName] = FieldValue;
            table.Rows.Add(row1);

            return table.CreateDataReader();
        }
    }

    public When_mapping_a_data_reader_to_a_dto_with_missing_columns_in_data_reader()
    {
        Mapper.Initialize(cfg => {
            cfg.Mappers.Insert(0, new DataReaderMapper());

            cfg.AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            cfg.CreateMap<IDataRecord, DtoWithMoreColumnsThanDataReader>();
        });

        _dataReader = new DataBuilder().BuildDataReaderWithMissingColumns();
    }

    [Fact]
    public void Then_results_should_be_as_expected()
    {
        while (_dataReader.Read())
        {
            var dto = Mapper.Map<IDataReader, DtoWithMoreColumnsThanDataReader>(_dataReader);

            dto.Integer.ShouldBe(FieldValue);

            // missing column
            dto.Integer2.ShouldBe(0);
            dto.String1.ShouldBeNull();
        }
    }

    private IDataReader _dataReader;
}

internal class FieldName
{
    public const String SmallInt = "SmallInteger";
    public const String Int = "Integer";
    public const String BigInt = "BigInteger";
    public const String Guid = "Guid";
    public const String Float = "Float";
    public const String Double = "Double";
    public const String Decimal = "Decimal";
    public const String DateTime = "DateTime";
    public const String Byte = "Byte";
    public const String Boolean = "Boolean";
    public const String Something = "Something";
}

public class DataBuilder
{
    public IDataReader BuildDataReader()
    {
        var authorizationSetDataTable = new DataTable();
        authorizationSetDataTable.Columns.Add(FieldName.SmallInt, typeof(Int16));
        authorizationSetDataTable.Columns.Add(FieldName.Int, typeof(Int32));
        authorizationSetDataTable.Columns.Add(FieldName.BigInt, typeof(Int64));
        authorizationSetDataTable.Columns.Add(FieldName.Guid, typeof(Guid));
        authorizationSetDataTable.Columns.Add(FieldName.Float, typeof(float));
        authorizationSetDataTable.Columns.Add(FieldName.Double, typeof(Double));
        authorizationSetDataTable.Columns.Add(FieldName.Decimal, typeof(Decimal));
        authorizationSetDataTable.Columns.Add(FieldName.DateTime, typeof(DateTime));
        authorizationSetDataTable.Columns.Add(FieldName.Byte, typeof(Byte));
        authorizationSetDataTable.Columns.Add(FieldName.Boolean, typeof(Boolean));
        authorizationSetDataTable.Columns.Add(FieldName.Something, typeof(DateTime));

        var authorizationSetDataRow = authorizationSetDataTable.NewRow();
        authorizationSetDataRow[FieldName.SmallInt] = 22;
        authorizationSetDataRow[FieldName.Int] = 6134;
        authorizationSetDataRow[FieldName.BigInt] = 61346154;
        authorizationSetDataRow[FieldName.Guid] = Guid.NewGuid();
        authorizationSetDataRow[FieldName.Float] = 642.61;
        authorizationSetDataRow[FieldName.Double] = 67164.64;
        authorizationSetDataRow[FieldName.Decimal] = 94341.61;
        authorizationSetDataRow[FieldName.DateTime] = DateTime.Now;
        authorizationSetDataRow[FieldName.Byte] = 0x12;
        authorizationSetDataRow[FieldName.Boolean] = true;
        authorizationSetDataRow[FieldName.Something] = DateTime.MaxValue;
        authorizationSetDataTable.Rows.Add(authorizationSetDataRow);

        return authorizationSetDataTable.CreateDataReader();
    }

    public IDataRecord BuildDataRecord()
    {
        var dataReader = BuildDataReader();
        dataReader.Read();
        return dataReader;
    }
}

public class DTOObject
{
    public Int16 SmallInteger { get; private set; }
    public Int32 Integer { get; private set; }
    public Int64 BigInteger { get; private set; }
    public Guid Guid { get; private set; }
    public float Float { get; private set; }
    public Double Double { get; private set; }
    public Decimal Decimal { get; private set; }
    public DateTime DateTime { get; private set; }
    public Byte Byte { get; private set; }
    public Boolean Boolean { get; private set; }
    public DateTime Else { get; private set; }
}

public class DerivedDTOObject : DTOObject { }

}

I think there is an issue with DI since now I got:

Message: AutoMapper.AutoMapperConfigurationException :
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters

IDataRecord -> DTOObject (Destination member list)
System.Data.IDataRecord -> AutoMapper.Data.Tests.DTOObject (Destination member list)

Unmapped properties:
SmallInteger
Integer
BigInteger
Guid
Float
Double
Decimal
DateTime
Byte
Boolean
Else

Any ideas for where to look during the investigation?

Thank you

Alessandro

When_mapping_a_data_reader_to_a_dto_with_nullable_enum

https://github.com/AutoMapper/AutoMapper.Data/blob/master/AutoMapper.Data.Tests/DataReaderMapping.cs#L433

The test is essentially rigged (Map call is commented out, and the mapping is performed manually) to present successful results.

However, when an actual mapping is attempted, - from IDataReader to a DTO with nullable enum member - the following exception is thrown:

AutoMapper.AutoMapperMappingException: 'Error mapping types.'
Inner exception:
InvalidCastException: Specified cast is not valid.

[ASP.NET CORE] IDataRecord mapping does not map properties having same name as columns in DataReader

When using the mapper via DI, mapping from a datareader having same column names as properties in destination object does not work (default values for properties)
I have created a simple sample solution to demonstrate the issue below:


   class dummydobj
    {
        public string bbb { get; set; }
        public string aaa { get; set; }
    }

    public class DummyProfile : Profile
    {
        public DummyProfile()
        {
            //without this properties get default values (null in this case)
            //AddMemberConfiguration().AddMember<DataRecordMemberConfiguration>();
            CreateMap<IDataRecord, dummydobj>();
        }
    }



    [ApiController]
    [Route("[controller]")]
    public class DummyController : ControllerBase
    {
        private readonly IMapper mapper;

        public DummyController(IMapper mapper)
        {
            this.mapper = mapper;
        }

        [HttpGet]
        public IActionResult Get()
        {
            var conn = new System.Data.SQLite.SQLiteConnection("Data Source=:memory:");
            conn.Open();
            var cmd = conn.CreateCommand();
            cmd.CommandText = "select 'valueaaa' as aaa,'valuebbb' as bbb";
            var rdr = cmd.ExecuteReader();
            var res = mapper.Map<IEnumerable<dummydobj>>(rdr);
            Debug.Assert(res.First().aaa != null,"should not be null");

            return Ok();
        }
    }


    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAutoMapper(cfg =>
            {
                cfg.AddDataReaderMapping();
            }, typeof(Startup));
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }


    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

Also i have tested this in a console app and the issue does not occur when creating the mapper like this:

`   var mapper = new MapperConfiguration(c =>
              {
                  c.AddDataReaderMapping();
                  c.CreateMap<IDataRecord, dummy>();
              }).CreateMapper();`

Using automapper 9.0 and automapper.data 4.1.0

Default Values only when Mapping List to DataReader

From @dworkman on December 5, 2014 22:8

After upgrading to 3.3, I only get the default values of my object when mapping a DataReader to a List.

For example, when this code is run:

Mapper.CreateMap<IDataRecord, ClientPrice>();

using (SqlDataReader reader = command.ExecuteReader())
{
    prices = Mapper.Map<IList<ClientPrice>>(reader);
}

The prices object correctly contains an object per row in the DataReader, but all of the values are null or their default value. The same code correctly populates the values in 3.2.1.

Copied from original issue: AutoMapper/AutoMapper#643

AutoMapper v9.0 vs AutoMapper.Data v4.0

When try to upgrade to the latest versions, I got the issue. The enumerable data has elements but element's data field is always empty.

My configs are below:

services.AddAutoMapper(cfg => {
                cfg.AddDataReaderMapping(false);
                cfg.AllowNullCollections = false;
                cfg.AllowNullDestinationValues = true;
            }, typeof(Startup));
public class UserMappingProfile : Profile
        {
            public UserMappingProfile()
            {
                CreateMap<IDataReader, User>();
            }
        }

And try to map to DTO:

using (var reader = (await ExecuteSqlQueryAsync(databaseFacade, sql, parameters)).DbDataReader)
            {
                var data = mapper.Map<IDataReader, IEnumerable<T>>(reader);
            }

The data.Count > 0 but all element's fields are default values.

Crash when using AddDataReaderMapping

https://gist.github.com/iulian0512/b8a36633eca9dfa91a88fd94ae2dbac8

using AutoMapper;
using AutoMapper.Data;
using System;
using System.Collections.Generic;
using System.Data;

namespace automappercrash
{

public interface dummyinterface
{
    string test();
}

public class dummy1
{
    public string name { get; set; }
    public dummyinterface tintf { get; set; }
}

public class dummy2
{
    public string aaa { get; set; }
    public dummy1 test { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var mapper = new MapperConfiguration(cfg =>
        {
            //this causes the crash, without it this example runs without any exceptions
           //System.ArgumentNullException: 'Value cannot be null.Parameter name: con'
            cfg.AddDataReaderMapping();

            cfg.CreateMap<IDataRecord, dummy2>()
            .ForMember(dto => dto.aaa, o => o.MapFrom(a => a["test"]))
            .ForAllOtherMembers(a => a.Ignore());
            

        });
    }
}

}

AutoMapper.Data

Hi,
It seems the v5.1.1 is breaking this utility class.

I tried locally to fix it. Can you help me please ?

Fixing the interface was easy, but am having an issue with this part, as the functions have been deprecated:

private void MapPropertyValue (ResolutionContext context, object mappedObject, PropertyMap propertyMap)**

  • propertyMap.ResolveValue(context);
  • propertyMap.DestinationProperty.SetValue(mappedObject, result.Value);

JIT compiler exception using IDataReader mapper

From @sloncho on May 28, 2013 18:54

While preparing an example code for a stackoverflow question, I encountered some runtime exception while running a nunit test demonstrating the mapping.

The code is here: https://gist.github.com/sloncho/5665084

I'm using VS2010, the project is set to .Net 4.0, AnyCpu, running on 64bit Windows 7 machine. I see the same behavior with Automapper 2.2.0, 2.2.1 and 3.0.0, all from nuget.

The exception is different, based on the nunit runner used, as well as the build config used.

Using NCrunch (debug), this is the exception:

AutoMapper.AutoMapperMappingException : 

Mapping types:
DataTableReader -> IList`1
System.Data.DataTableReader -> System.Collections.Generic.IList`1[[StackOverflowExample.Automapper.Address, StackOverflowExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

Destination path:
IList`1

Source value:
System.Data.DataTableReader
  ----> System.InvalidProgramException : JIT Compiler encountered an internal limitation.
   at StackOverflowExample.Automapper.DatasetRelations.GetDataFromDataTable[T](DataSet dataSet, String tableName) in C:\work\stackoverflow\StackOverflowExample\Automapper\DatasetRelations.cs:line 69#0
   at StackOverflowExample.Automapper.DatasetRelations.RelationMappingTest() in C:\work\stackoverflow\StackOverflowExample\Automapper\DatasetRelations.cs:line 56#1
--InvalidProgramException
   at DynamicCreate(IDataRecord )
   at AutoMapper.Mappers.DataReaderMapper.LoadDataReaderViaList(IDataReader dataReader, IMappingEngineRunner mapper, Build buildFrom, ResolutionContext resolveUsingContext, Type elementType)
   at AutoMapper.Mappers.DataReaderMapper.MapDataReaderToEnumerable(ResolutionContext context, IMappingEngineRunner mapper, Type destinationElementType, Boolean useYieldReturn)
   at AutoMapper.Mappers.DataReaderMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
   at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)

Using ReSharper, in Release config, the exception is:

AutoMapper.AutoMapperMappingException : 

Mapping types:
DataTableReader -> IList`1
System.Data.DataTableReader -> System.Collections.Generic.IList`1[[StackOverflowExample.Automapper.Address, StackOverflowExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

Destination path:
IList`1

Source value:
System.Data.DataTableReader
  ----> System.InvalidProgramException : Common Language Runtime detected an invalid program.
   at StackOverflowExample.Automapper.DatasetRelations.GetDataFromDataTable(DataSet dataSet, String tableName) in DatasetRelations.cs: line 69
   at StackOverflowExample.Automapper.DatasetRelations.RelationMappingTest() in DatasetRelations.cs: line 56
--InvalidProgramException
   at DynamicCreate(IDataRecord)
   at AutoMapper.Mappers.DataReaderMapper.LoadDataReaderViaList(IDataReader dataReader, IMappingEngineRunner mapper, Build buildFrom, ResolutionContext resolveUsingContext, Type elementType)
   at AutoMapper.Mappers.DataReaderMapper.MapDataReaderToEnumerable(ResolutionContext context, IMappingEngineRunner mapper, Type destinationElementType, Boolean useYieldReturn)
   at AutoMapper.Mappers.DataReaderMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
   at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)

And with Resharper, but in Debug, it is:

System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at DynamicCreate(IDataRecord)
   at AutoMapper.Mappers.DataReaderMapper.LoadDataReaderViaList(IDataReader dataReader, IMappingEngineRunner mapper, Build buildFrom, ResolutionContext resolveUsingContext, Type elementType)
   at AutoMapper.Mappers.DataReaderMapper.MapDataReaderToEnumerable(ResolutionContext context, IMappingEngineRunner mapper, Type destinationElementType, Boolean useYieldReturn)
   at AutoMapper.Mappers.DataReaderMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
   at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
   at AutoMapper.MappingEngine.Map(Object source, Action`1 opts)
   at StackOverflowExample.Automapper.DatasetRelations.GetDataFromDataTable(DataSet dataSet, String tableName) in DatasetRelations.cs: line 69
   at StackOverflowExample.Automapper.DatasetRelations.RelationMappingTest() in DatasetRelations.cs: line 56

Copied from original issue: AutoMapper/AutoMapper#342

AutoMapper 8.0.0 + AutoMapper.Data 2.0.0 = Not Implemented Exception

Mapping configuration

Mapper.Initialize(cfg => {
cfg.AddDataReaderMapping();
}

Version: AutoMapper v8.0.0, AutoMapper.Data v2.0.0

Expected behavior

No issue before with AutoMapper v7.0.1 and AutoMapper.Data v2.0.0.

Actual behavior

System.TypeLoadException: Method 'MapExpression' in type 'AutoMapper.Data.Mappers.DataReaderMapper' from assembly 'AutoMapper.Data, Version=2.0.0.0, Culture=neutral, PubliccKeyToken=null' does not have an implementation.

Steps to reproduce

Just setup AutoMapper v8.0.0 and AutoMapper.Data v2.0.0 and initialize it.

Readme incorrect for initialization

The readme explicitly suggests to use DI and AddAutoMapper(typeof(Startup), ...

I have the latest AutoMapper (12.0.1), AutoMapper.Data (7.0.2), AutoMapper.Extensions.Microsoft.DependencyInjection (12.0.1) and there is no such signature for AddAutoMapper().

I am having all sorts of grief trying to access DB2 using DB2DataReader (inherits IDataReader & IDataRecord interfaces) and mapping to a POCO, one record at a time. I have not found anything useful / working doing Google searches. Everything is either old (DataReader in 3.1.1) or requires an in-memory implementation (not feasible with 100million+ records).

IDataReader Exception.

From @elranu on January 10, 2014 17:7

Hi,
Im getting the following AutoMapperMappingException. Mapping a Reader to an Entity.How I can know which is the column is generating this error?

Mapping types:
IDataReader -> UserEntity
System.Data.IDataReader -> AMSDLL.Entities.UserEntity

Destination path:
UserEntity

Source value:
System.Data.SqlClient.SqlDataReader

Thanks and Regards!

Copied from original issue: AutoMapper/AutoMapper#441

Mapping data field of DateTimeOffset

When I have a field that is a DateTimeOffset, I get the error:
Value cannot be null. Parameter name: con at System.Reflection.Emit.DynamicILGenerator.Emit(OpCode opcode, ConstructorInfo con) at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.EmitPropertyMapping(ILGenerator il, Type destType, Type destMemberType, String nameToSearch) at AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, LinkedList1 resolvers, IMemberConfiguration parent)
at AutoMapper.Configuration.Conventions.MemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, LinkedList1 resolvers) at AutoMapper.ProfileMap.<>c__DisplayClass70_0.<MapDestinationPropertyToSource>b__0(IMemberConfiguration _) at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func2 predicate) at AutoMapper.ProfileMap.MapDestinationPropertyToSource(TypeDetails sourceTypeInfo, Type destType, Type destMemberType, String destMemberInfo, LinkedList1 members)
at AutoMapper.TypeMapFactory.CreateTypeMap(Type sourceType, Type destinationType, ProfileMap options)
at AutoMapper.ProfileMap.BuildTypeMap(IConfigurationProvider configurationProvider, ITypeMapConfiguration config)
at AutoMapper.ProfileMap.Register(IConfigurationProvider configurationProvider)
at AutoMapper.MapperConfiguration.Seal()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at AutoMapper.MapperConfiguration..ctor(Action1 configure) at CombinedPublic.Service.Repository.InmateRepository..ctor(ISqlClient sqlClient) in C:\\Users\\sklein\\source\\repos\\view-services\\CombinedPublic.Service\\Repository\\InmateRepository.cs:line 47"

I assume that in DataRecordMemberConfiguration.cs, DateTimeOffset needs to be added to _treatAsPrimitives. Is there any way to do this?

AutoMapper.Data throwing "Cannot install package error"

Hi,

I am trying to use auto mapper (6.2.1) and when I run the code I am not having it return any results when I map it with IDataReader. Below is the code.

public class AuthorModel {
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; } }

DataTable _dTable = new DataTable();
_dTable.Columns.Add("Id", typeof(string)); _
dTable.Columns.Add("FirstName", typeof(string));
_dTable.Columns.Add("LastName", typeof(string));
_dTable.Columns.Add("Address", typeof(string));

DataRow dRow = _dTable.NewRow();
_dRow["Id"] = "1";
_dRow["FirstName"] = "Ramachandran";
_dRow["LastName"] = "Veluthattil";
_dRow["Address"] = "ABCD EFGH IJKL";
_dTable.Rows.Add(dRow); dSet = new DataSet();
_dSet.Tables.Add(dTable);

var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<IDataReader, List>();
});
IMapper mapper = config.CreateMapper();
DataTableReader dr = _dSet.Tables[0].CreateDataReader();
List authors = mapper.Map<IDataReader, List>(dr);
return authors;

I changed it to use IEnumerable and also IList but when i use those it throws an error. The code above seems to work but no results are being generated. On doing some research I found that it has been mentioned that IDataReader implementation has been moved to AutoMapper.Data and to use that package. Now when i try to add that package i get the following error and it is not adding the package

Attempting to gather dependency information for package 'AutoMapper.Data.1.0.0' with respect to project 'AutoMapper', targeting '.NETFramework,Version=v4.5' Attempting to resolve dependencies for package 'AutoMapper.Data.1.0.0' with DependencyBehavior 'Lowest' Resolving actions to install package 'AutoMapper.Data.1.0.0' Resolved actions to install package 'AutoMapper.Data.1.0.0' Install failed. Rolling back... Package 'AutoMapper.Data.1.0.0' does not exist in project 'AutoMapper' Package 'AutoMapper.Data.1.0.0' does not exist in folder 'C:\Users\rveluth\Desktop\AutoMapper\packages' Could not install package 'AutoMapper.Data 1.0.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author. ========== Finished ==========

I am using studio 2015 and version is 14.0.25431.01 update 3. The framework version is 4.6.01055.

Can you please help/advise?

Depth property not mapped

I have a POCO class like this

public class MyClass
{
    public string Test {get; set; }
    public int? Depth {get; set;}
}

And I want to map an IDataReader (from DataTable) to a collection of MyClass.

AutoMapper.Mapper.Initialize(conf => MapperRegistry.Mappers.Add(new DataReaderMapper { EnableYieldReturn = true }));
AutoMapper.Mapper.CreateMap<IDataReader, MyClass>();
var result = AutoMapper.Mapper.DynamicMap<IDataReader, ICollection<MyClass>>(dataReader);

But when I do that, the Depth property is mapped from IDataReader.Depth and not from the Depth column.

Any clue?

Opcodes using a short-form index cannot address a local position over 255

Got an interesting issue here:

MapperConfiguration config = new MapperConfiguration(c => 
{
   c.AddDataReaderMapping();
   c.CreateMap<IDataReader, HugeClass>()
      .ForMember(dest => dest.Id, opt = opt.MapFrom(src => Convert.ToInt32(src["Id"])))
      .ForAllOtherMembers(o => o.Ignore());
});
config.AssertConfigurationIsValid();

HugeClass is a class with a lot of nested properties.
Configuration fails with exception 'Opcodes using a short-form index cannot address a local position over 255' in EmitPropertyMapping.
We get this exception because all il.DeclareLocal() calls come within one context and it does not support more than 255 variables.

I understand it is not a best practice to use such big classes, but what surprised me is that AutoMapper generates IL for all properties, even if we set them to Ignore. That doesn't look optimal to me.

NamingConventions not working to ignore underline and case

My source columns are all uppercase with underscores, such as FIRST_NAME, and the target columns are Pascal casing (FirstName). I cannot get these to map without using ForMember. I have tried:
Mapper.Initialize(cfg =>
{
cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention();
cfg.AddDataReaderMapping();
cfg.CreateMap<IDataReader, Employee>()

How can I get these to map automatically?

.Map<IDataReader, FooDto> not mapping custom ForMember

All but one of my DTO members are mapped fine, but the one with a different property name (ForMember) doesn't get mapped.

I have a DTO class:

public class FooDto
{
   ...
   public string UserId {get; set;}
}

My database record has a string column "Id" that I want to map into FooDto, UserId. My configure includes:

CreateMap<IDataReader, FooDto>()
   .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.GetString(src.GetOrdinal("Id"))));

When I call:

var records = mapper.Map<IDataReader, IEnumerable<FooDto>>(reader);

The records include the value for all properties except the "Id" column. In fact, I can do this and my records are still missing a value:

CreateMap<IDataReader, FooDto>()
   .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => "abc")));

I don't think the ForMember code is being executed at all during the IDataReader mapping. Any ideas?

Using AutoMapper 7.0.1 and AutoMapper.Data 2.0.0.

DynamicMap Does not Work with AutoMapper.Data

This Line worked in Automapper < 4.0

var tests = Mapper.DynamicMap<IDataReader, List>(reader);

The reason it crashes I think is that no maps are created for IDataReader and TestDto. And I although didn't find Tests that cover this case.

ArgumentNullException thrown while calling CreateMap with object that has a collection member

public class MemberDto
{
    public IList<CardDto> Cards { get; set; }
}

public class CardDto
{
    public string CardNumber { get; set; }
    public string Amount { get; set; }
}

public sealed class MemberProfile : Profile
{
    AddMemberConfiguration()
        .AddMember<DataRecordMemberConfiguration>();
    CreateMap<IDataReader, MemberDto>()
        .ForMember(dest => dest.Cards, opt => opt.Ignore());
}

var config = new MapperConfiguration(cfg =>
{
    cfg.AddMaps(GetType().Assembly); // This throws "Value cannot be null. Parameter name: con"
});

Tried to solve it for hours... Anyone having the same issue?

Mapping to byte array property throws ArgumentNullError

Hello!
I'm using AutoMapper.Data package and trying to map from IDataReader to my DTO object, containing byte[] property.
When I call extension method AddDataReaderMapping(), it throws ArgumentNullExpression, due to argument "con" of ILGenerator's method Emit, that your DataRecordMemberConfiguration class calls, is null. That's right, because byte array hasn't parameterless ctor.

Map<IDataReader, MyType>(sourceReader, destinationObject) ignores the destination argument and tries to create a new instance

From @SonOfPirate on March 28, 2013 12:33

From: https://groups.google.com/forum/?fromgroups#!topic/automapper-users/lJzFXLqOmGs

It appears that calling Map<IDataReader, MyType>(sourceReader, destinationObject) ignores the destination argument and tries to create a new instance. Because my type doesn't have a default constructor, I get an exception.

Not sure why this isn't implemented consistently as there is an expectation what the behavior is and the actual mapper used should be required to satisfy the contract established by the Mapper/MappingEngine.

Copied from original issue: AutoMapper/AutoMapper#319

IDataReader, Mapping smallint to bool no error is thrown, bool value incorrect

Hello the guys from https://github.com/AutoMapper/AutoMapper told me to move the issue here.

Hello,

first let me say, great project and perfect functionality.
But i have struggled with one "bug".
AutoMapper is using dynamic generated MSIL code to read from the IDataReader.
In out Database bool are representated by smallint (-1 = true, 0 = false) normaly no problem, when we cast the -1 or 0 to a bit (CAST(-1 AS Bit)).
But if we will not do that, than Automapper or. the generated MSIL recognize that the source (database-column) is a smallint (int16 in .net). The issue in this point is that no exception gets thrown!
The "callvirt" in MSIL writes the int16 -1 to the bool property! No Exception! But if you look in the memory, then the bool is not 0x01 or 0x00, its 0xFF, because the representation of -1 in binary is 0xFFFF. When comparing the resulting bool with the == operator then all works fine. But when we are comparing by "PropertyOnEntity".Equals(true) then the result is false even if "PropertyOnEntity" is true! The reason of that is the MSIL of the .Equals in the Boolean Class. Its convertig the bool to in Int32 and comparing it by 1. Really you really have to see this!

MSIL og Boolean.Equals(true):

.method public hidebysig newslot virtual final 
        instance bool  Equals(bool obj) cil managed
{
  .custom instance void __DynamicallyInvokableAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldind.u1
  IL_0002:  ldarg.1
  IL_0003:  ceq
  IL_0005:  ret
} // end of method Boolean::Equals

UnitTest and Memory View:

        const string connectionString =
            "server=****;user id=****;password=****;database=****;MultipleActiveResultSets=True";

        using (var connection = new SqlConnection(connectionString))
        using (var command = connection.CreateCommand())
        {
            connection.Open();

            command.CommandText =
                "SELECT -1 AS CheckDispo";

            var sqlDataReader = (IDataReader) command.ExecuteReader();

            var resultList = Mapper.DynamicMap<List<Item>>(sqlDataReader);

            var a = resultList[0].CheckDispo.Equals(true); // false
            var b = resultList[0].CheckDispo == true; // true

            b.Should().BeTrue(); // works
            a.Should().BeTrue(); // fails
        }

image

image

image

Memory with "SELECT -1 AS CheckDispo"

image

Memory with "SELECT 3 AS CheckDispo"

image

MyGet feed

It would be great to get this added to the AutoMapper MyGet feed!

AutoMapper.Data has no strong name

I tested AutoMapper.Data the Compiler complained that it has no strong name.
This is because my Project is strongly named so Automapper.Data has to be strongly named too.

Automapper custom converter for DataReader

From @venkatavijay on October 27, 2014 10:40

Hi ,

I am using Custom Converter which converts DateTime to string
and the source is DataTable here,
Destination is a list of custom object

 Mapper.Reset();
            Mapper.CreateMap<long, string>().ConvertUsing(new IdConverter());
            Mapper.CreateMap<DateTime, string>().ConvertUsing(new DateTimeTypeConverter());
            Mapper.CreateMap<IDataReader, CustomerModel>()
                .ForMember(dest => dest.ComputedActivityDateTime,
                    opt =>
                        opt.MapFrom(
                            src =>
                                Convert.ToDateTime(src.GetValue(src.GetOrdinal("ActivityDateTime")).ToString())))
                .ForMember(dest => dest.ComputedTransactionLogId,
                    opt =>
                        opt.MapFrom(
                            src =>
                                    HttpUtility.UrlEncode(Cryptor.Encrypt(src.GetValue(src.GetOrdinal"TransactionLogId")).ToString()))));
            var records = AutoMapper.Mapper.Map<IDataReader, List<CustomerModel>>(
                logs.UsageLogs.Tables[0].CreateDataReader());

Basically i am using two custom converter here.One for Id and one for DateTime to String.
Both the converters are not called and I have to use ForMember.

My Custom Conveter is as below

public class DateTimeTypeConverter : ITypeConverter<DateTime, string>
    {
        public string Convert(ResolutionContext context)
        {
            var dateTimeOffset = new DateTimeOffset(DateTime.SpecifyKind((DateTime)context.SourceValue, DateTimeKind.Utc));
                          //  var dateTimeOffset =(DateTimeOffset)context.SourceValue;
            return dateTimeOffset.ConvertToDisplayDateWithTime();
        }
    }

Could you please let me know if i can avoid using ForMember and make it call CustomConverter defined.
I have some business logic to add TimeZone Offset to my DateTime which i handled in CustomConverter.
This is the reason i want to call Custom Converter and avoid ForMember usage.
Could you please help me with this.

Thanks,

Copied from original issue: AutoMapper/AutoMapper#616

IDataReader mapping using SourceMemberNamingConvention and RecognizePrefixes not working

From @CalvinRodo on April 23, 2014 19:15

When I map from an IDataReader it ignores the SourceMembernamingConvention, and the RecognizePrefixes

I'm using

SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();  

RecognizePrefixes(new[] { "po_" });

as a very basic example I'm mapping from po_err_msg -> ErrMsg and it's not working.
Both of those settings don't work with IDataReader.

Copied from original issue: AutoMapper/AutoMapper#507

Automapper running under IIS 8.0 (Win 2012 R2) - Common Language Runtime detected an invalid program

Hi,

I am currently using Automapper 4 via NuGet and it seems to be working fine on all developer machines which use IIS Express. As soon as I deploy to the server (Win 2012 R2), I get the dreaded "Common Language Runtime detected an invalid program exception".

Interestingly the problem doesn't when I am using dynamic map, only when I try to create an explicit map as shown by creating a custom profile.


protected override void Configure()
{
Mapper.CreateMap<IDataReader, SalesInfo>()
.ForMember(dest => dest.IsWipType,
option =>
option.MapFrom(
row =>
(YesNo)
Enum.Parse(typeof(YesNo),
row["IsWipType"].ToString(), true)));
}


I have tried the solution provided under AutoMapper/AutoMapper#242 but no luck as the patch is not applicable to my server.

The solution provided under AutoMapper/AutoMapper#664 doesnt seem to apply to me as even if I remove the explicit mappings, it give the same error.

NOTE: This problem does not happen when run as a console application on the same server. Only when run inside regular IIS.

The error that I get is as follows:


AutoMapper.AutoMapperMappingException was unhandled by user code
HResult=-2146233088
Message=

Mapping types:
IDataReader -> IList1 System.Data.IDataReader -> System.Collections.Generic.IList1[[Domain.CategoryInfo, Domain, Version=0.9.5582.23112, Culture=neutral, PublicKeyToken=null]]

Destination path:
IList`1

Source value:
System.Data.DataTableReader
Source=AutoMapper
StackTrace:
at DomainServices1.CategoryInfoServiceAccess.GetAllCategoryInformation(Int32 companyId) in c:\Users\Documents\Visual Studio 2013\Projects\MvcApplication1\MvcApplication1\CategoryInfoServiceAccess.cs:line 31
at MvcApplication1.Controllers.ValuesController.d__2.MoveNext() in c:\Users\Documents\Visual Studio 2013\Projects\MvcApplication1\MvcApplication1\Controllers\ValuesController.cs:line 40
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Newtonsoft.Json.Serialization.JsonArrayContract.CreateWrapper(Object list)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value)
at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClassd.b__c()
at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
InnerException: System.InvalidProgramException
HResult=-2146233030
Message=Common Language Runtime detected an invalid program.
Source=Domain
StackTrace:
at DynamicCreate(IDataRecord )
at AutoMapper.Mappers.DataReaderMapper.LoadDataReaderViaList(IDataReader dataReader, IMappingEngineRunner mapper, Build buildFrom, ResolutionContext resolveUsingContext, Type elementType) in c:\dev\AutoMapper\src\AutoMapper\Mappers\DataReaderMapper.cs:line 78
at AutoMapper.Mappers.DataReaderMapper.MapDataReaderToEnumerable(ResolutionContext context, IMappingEngineRunner mapper, Type destinationElementType, Boolean useYieldReturn) in c:\dev\AutoMapper\src\AutoMapper\Mappers\DataReaderMapper.cs:line 69
at AutoMapper.Mappers.DataReaderMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) in c:\dev\AutoMapper\src\AutoMapper\Mappers\DataReaderMapper.cs:line 29
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) in c:\dev\AutoMapper\src\AutoMapper\MappingEngine.cs:line 246
InnerException:

Thanks for your help!

Method 'Map' in type 'AutoMapper.Data.DataReaderMapper' from assembly 'AutoMapper.Data' does not have an implementation

I'm trying to map DataTable having customer details to List. Here is the configuration I put

MapperConfiguration config = new MapperConfiguration(cfg =>
{
MapperRegistry.Mappers.Add(new DataReaderMapper() { YieldReturnEnabled = true });
cfg.CreateMap<IDataReader, Customer>();
//Remaining Config
cfg.CreateMap<>();
}

The above configuration is getting initialized in App_Start method. Below is the exception I'm getting it. I didn't understand what I'm missing here. If I remove below two lines from the above configuration, everything works fine.

MapperRegistry.Mappers.Add(new DataReaderMapper() { YieldReturnEnabled = true });
cfg.CreateMap<IDataReader, Customer>();

Exception Message:

Method 'Map' in type 'AutoMapper.Data.DataReaderMapper' from assembly 'AutoMapper.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

This is how I'm calling.

mapper.Map<IDataReader, List<Customer>>(dt.CreateDataReader());

Documentation says to use Mapper.Initialize() but this method seems deprecated in the latest AutoMapper.

Please let me know how to use DataReaderMapper with the latest AutoMapper approach. Paste few working lines of code on how to use it.

Thanks,
Tulasi.

.Map is not working with IDataReader

I'am currently trying to map the output of a IDataReader to a Dto, but no Properties are being mapped.
My Mapper Config looks like this:

var mapperConfig = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<IDataReader, Country>();
            });

And The Country looks like this:

public class Country : IDbEntity {
        public int Id { get; set; }
        public string Name { get; set; }
    }

To Map the Dtos im using the .Map function like this:

await using var reader = await command.ExecuteReaderAsync();
                while (reader.Read())
                {
                    items.Add(Mapper.Map<T>(reader));
                }

In my database the country has the columns id and name
However AutoMapper doesn't map the properties. And i'm also not getting any error message

It works if i manually configure it with .ForMember, but there isn't much auto in that.

Automapper.Data doesn't work with Automapper version 6.2.2

Hi,
I used the latest automapper from nuget (v 6.2.2) together with automapper.data, everything compiles, but when running, it throws this error:
Method not found: 'System.Linq.Expressions.Expression AutoMapper.Mappers.Internal.CollectionMapperExpressionFactory.MapItemExpr(AutoMapper.IConfigurationProvider, AutoMapper.ProfileMap, AutoMapper.PropertyMap, System.Type, System.Type, System.Linq.Expressions.Expression, System.Linq.Expressions.ParameterExpression ByRef)'.

I tried with the automapper.data.tests project and got the same error if I upgrade automapper to 6.2.2.

Can you have a look?

Many Thanks

Where do I get AutoMapper.Data?

I tried to update from 3.3.1 to 4.0.4 and it removed AutoMapper.Net4.dll, this caused things like the workaround

private static readonly Type DataReaderType = typeof(AutoMapper.Mappers.DataReaderMapper);

discussed in issue #11 no longer work, not being able to find the DataReaderMapper type. I assume Automapper.Net4 is now AutoMapper.Data, but I don't see it listed on NuGet nor do I see where to download it here.

Are my assumptions incorrect that this is a 2nd library I need to download? If so where is DataReaderMapper located in 4.0.4?

Mapping issue

I am using automapper v4.1.1 and automapper.data1.0.0.beta 1. I have console app and my mapping code looks like:

` Mapper.Initialize(cfg => {
MapperRegistry.Mappers.Add(new DataReaderMapper {YieldReturnEnabled = true}

            );
            // Other config
            cfg.CreateMap<IDataRecord, AircraftDetails>();

        });`

And my db call code and mapping looks like

`var aircraft=new AircraftDetails();
using (SqlConnection connection =
new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings[_connectionString].ConnectionString))
{
SqlCommand command =
new SqlCommand(storedProcedureAsString, connection);

            command.AddInputParameters(new {a=aircraftId});

            connection.Open();

            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
               
               var res = Mapper.Map<IDataReader, IEnumerable<AircraftDetails>>(reader);

                aircraft = res.FirstOrDefault();
            }
            
        }

        return aircraft;`

When i run this code i get error:

Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
at DynamicCreate(IDataRecord )
at AutoMapper.Data.DataReaderMapper.d__10.MoveNext()
at System.Linq.Enumerable.d__941.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source)

Any ideas what I am doing wrong?

Cheers

Ismail

IDataReader mapper not applying Custom Type Converter

Hello,

I have the following code

      mapper = new Mapper(
                new MapperConfiguration(x =>
            {
                x.CreateMap<System.Decimal, System.String>()
                    .ConvertUsing( d => Convert.ToString(d));
                // DataReaderMappings
                x.AddDataReaderMapping();
                x.CreateMap<IDataRecord, TypeWithStringProperties>();

In my DB there are some numeric types which are being resolved to Decimal coming in. Instead of casting on the db side i thought i could simply define a converter using automapper to call the C# native wrapper class method ToString() method to convert the decimal to the string property in the 'TypeWithStringProperties' object.

However, I am noticing that the custom type converter is not applying my mapping from decimal to string in the IDataRecord to TypeWithStringProperties mapping.

Is there something I am doing incorrectly? or this a bug?

AutoMapper 12.0.0 support?

I'm in the process of sorting out dependencies for a .NET 7 upgrade. AutoMapper 12.0.0 seems to have some updates that make it more .NET 7 friendly. Is there work in progress yet for AutoMapper.Data support for AutoMapper 12.0.0? Thank you!

Automapper.Mappers.DataReaderMapper is not being loaded

Hi,

I posted a question to Stackoverflow.com (http://stackoverflow.com/questions/30470341/datatable-to-list-automapperexception-or-values-dont-get-mapped) but I also wanted to report this here.

I'm having an issue w/ AutoMapper (3.3.1) VS 2013 Progressional, Windows 7 Professional 64bit. Setting up, I have this code:

// gets called in application_start
public static void ConfigureMapping() {
    // ...
    AutoMapper.Mapper.CreateMap<SubObjectClassModel, LUSubObjectClass>();
        AutoMapper.Mapper.CreateMap<LUSubObjectClass, SubObjectClassModel>()
            .ForMember(x => x.ObjectClassCode,
                y => y.MapFrom(x => x.LUObjectClass.Code))
            .ForMember(x => x.ObjectClassGroupCode,
                y => y.MapFrom(x => x.LUObjectClass.GroupCode));

   AutoMapper.Mapper.CreateMap<IDataReader, SubObjectClassModel>();
  // also tried this AutoMapper.Mapper.CreateMap<IDataReader, List<SubObjectClassModel>>();
}
public class SubObjectClassModel
    {
        public int Id { get; set; }
        public int ObjectClassId { get; set; }
        public string ObjectClassCode { get; set; }         
        public string ObjectClassGroupCode { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string ColumnDisplayName { get; set; }
        public bool IncludeInProjections { get; set; }
        public bool IncludeInFormulas { get; set; }
        public bool IsSalaryProjectionBucket { get; set; }
        public bool IsBenefitProjectionBucket { get; set; }
        public bool IsLeo { get; set; }
        public bool IsFixed { get; set; }
        public bool IsDiscretionary { get; set; }
        public string UpdatedBy { get; set; }
        public DateTime UpdatedDate { get; set; }
    }
// after running a query that returns a datatable with multiple rows. the datatable includes all fields in the Model class using ThisCasing
public static List<SubObjectClassModel> Gets()
    {
        LUSubObjectClass subObjectClass = new LUSubObjectClass();
        return Mapper.Map<IDataReader, List<SubObjectClassModel>>(
            subObjectClass.Gets().CreateDataReader()
        );
    }

Three scenarios occur with this issue:

  • After deploying to the server I get this error.
Missing type map configuration or unsupported mapping. Mapping types: IDataReader -> List`1 System.Data.IDataReader -> System.Collections.Generic.List`1[[BRS.Models.Common.SubObjectClassModel, BRS.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] Destination path: List`1 Source value: System.Data.DataTableReader
  • When running locally, if I rebuild the entire solution, everything works fine.
  • When running locally, if I make a change to the web layer and run the projection, which only rebuilds the web layer, I get an empty list back. Nothing gets mapped at all.

I have multiple objects that fit this scenario and they are all behaving the same way.

Upon further investigation I noticed the following by placing a watch on Mapper. When I do a run from VS without rebuilding the entire solution and I see no results being returned after the Mapper.Map call, I see all the mappings listed correctly under the Mapper object. However, Automappers.Mapper.DataReaderMapper is not listed under AutoMapper.ConfigurationStore.

When results are returned successfully, usually after I rebuild the solution, this mapper is listed.

What would cause that behavior and how can I ensure the DataReaderMapper gets loaded every time?

Thanks much for your help!

The AutoMapper.Data 4.1.0 is incompatible with AutoMapper 10.0.0.

When AutoMapper is updated 10.0.0 , The AutoMapper.Data doesn't work properly

System.TypeLoadException : Method 'MapDestinationPropertyToSource' in type 'AutoMapper.Data.Configuration.Conventions.DataRecordMemberConfiguration' from assembly 'AutoMapper.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=c81663b416b68723' does not have an implementation.

···
ConfigurationExtensions.AddDataReaderMapping(IMapperConfigurationExpression configuration, Boolean enableYieldReturn)
<>c__71.<MapTo>b__7_1(IMapperConfigurationExpression cfg) 行 162 MapperConfiguration.Build(Action1 configure)
MapperConfiguration.ctor(Action1 configure) <>c__71.b__7_0() 行 160
···

I don't know what to do. 😭

Cannot map an integer DataTable Column in a long Dto property

I have a table in SQLServer with a int column.
I cannot map this int column in my Dto class with long property. I have an InvalidCastException.

How can I solve this issue without explicitly casting each source element to be mapped using forMember?
Etc. something like ForAllMembers()..Condition...Resolve?!?!

Thanks for help.

Sql time(7) type to C# TimeSpan type mapping error

Hello!

I have a class:

public class Calendar {
public string Description { get; set; }
public string Name { get; set; }
public string FullDescription { get; set; }
public int PersonId { get; set; }
public string Room { get; set; }
public TimeSpan TimeBegin { get; set; }
public TimeSpan TimeEnd { get; set; }
public string TypeWorkName { get; set; }
}

DataReader returns columns with corresponding types:

NVarChar -> String,
Int -> Int,
Time(7) -> TimeSpan

Trying to map with:

config.CreateMap<IDataReader, Calendar>();

But I got error:

Value cannot be null. Parameter name: con
This error throws only when class has properties with TimeSpan type.

Help! How to workaround this problem?

DotNetCore 2.0
AutoMapper version 6.2.1,
AutoMapper.Data version 1.0.0

Failing to load assembly

Hi,

I'm trying to support some legacy code that broke since our recent update to 5.0.2 of automapper. I discovered this separate repository and installed it along with adding this code,

AutoMapper.Mapper.Initialize(cfg => { MapperRegistry.Mappers.Add(new DataReaderMapper { YieldReturnEnabled = true }); // Other config });

It immediately breaks on this code failing to load Automapper.Data. Is this a known issue?

Thanks!

Error when running in Azure Function, Method not found: AddMemberConfiguration()

Hi,
I ran the following code in LINQPad 7 with .NET 3.1 selected and it works.
But when I run it from an Azure Function locally on my dev machine, it doesn't.
Seems like an issue.

Any help would be appreciated.

The error:

[2022-11-02T17:37:20.058Z] PoChangeNotif trigger function, executed at: 11/2/2022 1:37:20 PM
[2022-11-02T17:37:20.086Z] System.MissingMethodException: Method not found: 'AutoMapper.Configuration.Conventions.IMemberConfiguration AutoMapper.Internal.IProfileExpressionInternal.AddMemberConfiguration()'.
[2022-11-02T17:37:20.090Z]    at AutoMapper.Data.ConfigurationExtensions.AddDataRecordMember(IProfileExpression profile)[2022-11-02T17:37:20.092Z]    at AutoMapper.Data.ConfigurationExtensions.AddDataReaderMapping(IMapperConfigurationExpression configuration, Boolean enableYieldReturn)
[2022-11-02T17:37:20.093Z]    at AutoMapper.Data.ConfigurationExtensions.AddDataReaderMapping(IMapperConfigurationExpression configuration)
[2022-11-02T17:37:20.095Z]    at Project.AzureAlerts.VendorPoChangeNotifFunction.<>c.<Run>b__1_0(IMapperConfigurationExpression cfg) in D:\Dev\VS2019\Project.AzureAlerts\Project.AzureAlerts\VendorPoChangeNotifFunction.cs:line 33
[2022-11-02T17:37:20.096Z]    at AutoMapper.MapperConfiguration.Build(Action`1 configure)
[2022-11-02T17:37:20.097Z]    at AutoMapper.MapperConfiguration..ctor(Action`1 configure)
[2022-11-02T17:37:20.098Z]    at Project.AzureAlerts.VendorPoChangeNotifFunction.Run(TimerInfo myTimer, ILogger log) in D:\Dev\VS2019\Project.AzureAlerts\Project.AzureAlerts\VendorPoChangeNotifFunction.cs:line 31

References:

    <PackageReference Include="AutoMapper.Data" Version="6.0.0" />
    <PackageReference Include="DevExpress.Xpo" Version="22.1.6" />
    <PackageReference Include="DotLiquid" Version="2.2.656" />
    <PackageReference Include="MailKit" Version="3.4.1" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.1.2" />

The code:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using AutoMapper;
using AutoMapper.Data;
using Project.AzureAlerts.Models;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace Project.AzureAlerts
{
    public static class VendorPoChangeNotifFunction
    {
        [FunctionName("PoChangeNotif")]
        public static void Run([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"PoChangeNotif trigger function, executed at: {DateTime.Now}");

            IMapper map;
            try
            {
                var config = new AutoMapper.MapperConfiguration(cfg =>
                {
                    cfg.AddDataReaderMapping();
                    cfg.CreateMap<IDataReader, ChangePoRecord>();
                });

                map = config.CreateMapper();
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.ToString());

                throw ex;
            }

            InitializeDatabase();

            var sql = 
@"select upo.*, ven.email
from [dbo].[vwPurchOrders] upo
inner join dbo.Vendors ven ON upo.VendorID = ven.pk
where ven.portal= 1";

            var selectedData = XpoDefault.Session.ExecuteQueryWithMetadata(sql);

            var reportTable = BuildTableFromXpoResult(selectedData);

            var list = new List<ChangePoRecord>();
            var reader = reportTable.CreateDataReader();
            while(reader.Read())
            {
                list.Add(map.Map<ChangePoRecord>(reader));
            }

            log.LogInformation($"fifth PONo: {list[4].PONo}");
        }
    // ... more stuff
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.