Исключение при использовании AutoMapper с Entity Framework

Я пытаюсь включить Automapper в проект с помощью Entity Framework, это мой класс DTO:

public class FunctionDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public string Comment { get; set; }
    public DateTime? ExaminationDate { get; set; }
    public string Place { get; set; }
}

И сначала класс домена с кодом:

public class Function
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public string Comment { get; set; }
    public DateTime? ExaminationDate { get; set; }
    public string Place { get; set; }

    public virtual List<Employee> Employees { get; set; }
}

Конфигурация автомаппера:

public static class AutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(config => config.AddProfile<FunctionProfile>());
    }
}

public class FunctionProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Function, FunctionDto>()
        .ForMember(dto => dto.Id, opt => opt.MapFrom(src => src.Id))
        .ForMember(dto => dto.Name, opt => opt.MapFrom(src => src.Name))
        .ForMember(dto => dto.Comment, opt => opt.MapFrom(src => src.Comment))
        .ForMember(dto => dto.StartDate, opt => opt.MapFrom(src => src.StartDate))
        .ForMember(dto => dto.EndDate, opt => opt.MapFrom(src => src.EndDate))
        .ForMember(dto => dto.ExaminationDate, opt => opt.MapFrom(src => src.ExaminationDate))
        .ForMember(dto => dto.Place, opt => opt.MapFrom(src => src.Place));
    }   
}

Затем используйте в WebApi:

var functionDtos = functions
            .AsQueryable()
            .OrderBy(sort)
            .Skip(start)
            .Take(count)
            .ToList()
            .Select(Mapper.Map<FunctionDto>);

Конечно, я зарегистрировался в Global:

 AutoMapperConfiguration.Configure();

Но у меня есть исключение:

Отсутствует конфигурация карты типов или неподдерживаемое сопоставление

Что не так с приведенным выше кодом?


person cuongle    schedule 29.11.2012    source источник
comment
Не ответ (пока), но этого достаточно, чтобы сделать CreateMap<Function, FunctionDto>();, потому что все участники имеют одинаковые имена. Что произойдет, если вы поместите оператор инициализации непосредственно перед запросом linq? (Просто для попытки)   -  person Gert Arnold    schedule 29.11.2012
comment
@GertArnold: Dto не имеет сотрудников и просто скажу прямо. Я попробовал functions.Select(Mapper.Map<FunctionDto>), но все равно получаю ту же ошибку. Также функция здесь - это прокси-класс из-за ленивой загрузки   -  person cuongle    schedule 29.11.2012
comment
Я использую AutoMapper 2.1 (Nuget), и он отображает прокси в dto v.v. Я знаю, что прокси-серверы могут вызывать проблемы (здесь, в SO, были вопросы по этому поводу), но, похоже, это нормально в той версии, которую я использую.   -  person Gert Arnold    schedule 29.11.2012


Ответы (2)


Не могли бы вы подтвердить, что такое functions, когда проходят следующие этапы:

MapperConfiguration.cs

namespace StackOverflow.Function
{
    using AutoMapper;

    public class MyProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<Function, FunctionDto>();
        }
    }
}

MappingTests.cs

[TestFixture]
public class MappingTests
{
    [Test]
    public void AutoMapper_Configuration_IsValid()
    {
        Mapper.Initialize(m => m.AddProfile<MyProfile>());
        Mapper.AssertConfigurationIsValid();
    }

    [Test]
    public void AutoMapper_Mapping_IsValid()
    {
        Mapper.Initialize(m => m.AddProfile<MyProfile>());
        Mapper.AssertConfigurationIsValid();

        var functions = new List<Function>
            {
                new Function
                    {
                        Comment = "Stack Overflow Rocks",
                        EndDate = new DateTime(2012, 01, 01),
                        ExaminationDate = new DateTime(2012, 02, 02),
                        Id = 1,
                        Name = "Number 1",
                        Place = "Here, there and everywhere",
                        StartDate = new DateTime(2012, 03, 03)
                    },
                new Function
                    {
                        Comment = "As do I",
                        EndDate = new DateTime(2013, 01, 01),
                        ExaminationDate = new DateTime(2013, 02, 02),
                        Id = 2,
                        Name = "Number 2",
                        Place = "Nowhere",
                        StartDate = new DateTime(2013, 03, 03)
                    }
            };

        var functionDtos = functions
            .AsQueryable()
            .OrderBy(x => x.Id)
            .Skip(1)
            .Take(1)
            .ToList()
            .Select(Mapper.Map<FunctionDto>);

        Assert.That(functionDtos, Is.Not.Null);
        Assert.That(functionDtos.Count(), Is.EqualTo(1));
        Assert.That(functionDtos.First().Id, Is.EqualTo(2));
    }
}
person Mightymuke    schedule 30.11.2012

Попробуйте этот Configure() метод,

Примечание. Если Function, FunctionDto имеет одинаковые свойства имени, отображать не нужно. AutoMapper позаботится о картировании.

protected override void Configure()
{
    CreateMap<Function, FunctionDto>().IgnoreAllNonExisting();
}

--

    public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var sourceType = typeof(TSource);
        var destinationType = typeof(TDestination);
        var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
        foreach (var property in existingMaps.GetUnmappedPropertyNames())
        {
            expression.ForMember(property, opt => opt.Ignore());
        }
        return expression;
    }
person Prasad Kanaparthi    schedule 30.11.2012