将 AutoMapper 与实体框架一起使用时出现异常
Posted
技术标签:
【中文标题】将 AutoMapper 与实体框架一起使用时出现异常【英文标题】:Exception using AutoMapper with Entity Framework 【发布时间】:2012-11-17 05:49:25 【问题描述】:我正在尝试使用实体框架将 Automapper 包含到项目中,这是我的 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>);
当然我已经在全球注册了:
AutoMapperConfiguration.Configure();
但我得到了例外:
缺少类型映射配置或不支持的映射
上面的代码有什么问题?
【问题讨论】:
不是一个答案(还),但这样做就足够了CreateMap<Function, FunctionDto>();
,因为所有成员都有相同的名字。如果将初始化语句放在 linq 查询之前会发生什么? (仅供尝试)
@GertArnold:Dto 没有员工,只是很明确。我试过functions.Select(Mapper.Map<FunctionDto>)
仍然得到同样的错误。由于延迟加载,这里的函数也是代理类
我使用 AutoMapper 2.1 (Nuget),它从代理映射到 dto 的 v.v.我知道代理可能会导致问题(在 SO 这里有关于它的问题),但在我使用的版本中似乎没问题。
【参考方案1】:
请您确认functions
是什么,如下所示:
MapperConfiguration.cs
namespace ***.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));
【讨论】:
【参考方案2】:试试这个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;
【讨论】:
以上是关于将 AutoMapper 与实体框架一起使用时出现异常的主要内容,如果未能解决你的问题,请参考以下文章
使用 Automapper,将 DTO 映射回实体框架,包括引用的实体