Automapper 首先映射 EF 可投影属性,然后是其他属性
Posted
技术标签:
【中文标题】Automapper 首先映射 EF 可投影属性,然后是其他属性【英文标题】:Automapper mapping EF projectable properties first, then other properties 【发布时间】:2014-03-12 18:48:45 【问题描述】:我有这样的事情:
Mapper.CreateMap<UserProfile, UserDTO>()
.ForMember(t => t.UserImage, s => s.MapFrom(x => x.Picture(32)))
.ForMember(t => t.Permalink, s => s.MapFrom(x => x.Permalink()));
我尝试这样的事情:
unit.UserProfiles.GetAll().Project().To<UserDTO>().First();
我得到类似的东西:
LINQ to Entities does not recognize the method 'System.String Picture(xx.xxx.UserProfile, Int32)' method, and this method cannot be translated into a store expression.
我想告诉 automapper 映射除这两个之外的所有属性,并且在查询完成后以正常方式映射这两个,是否可行?
【问题讨论】:
【参考方案1】:你在这里问错了问题。您确实需要问“我的基础查询提供程序如何将某些投影推迟到可查询对象完成其工作之后”。这将涉及实体框架需要支持的两步过程。这是代码,没有 AutoMapper 继续:
unit.UserProfiles.Select(profile => new UserDTO
Id = profile.Id, // I made these two up
Name = profile.Name,
UserImage = profile.Picture(32),
Permalink = profile.Permalink()
).First();
EF 将如何解释这一点?不太好,我猜。大概是个例外。如果您想在 EF 中执行此操作,则需要执行以下操作:
unit.UserProfiles.Select(profile => new UserDTO
Id = profile.Id, // I made these two up
Name = profile.Name
UserImage = profile.UserImage,
Slug = profile.Slug
).First();
然后将创建图片的逻辑包含在 UserDTO 中。
或者,您只需将用户取出,然后再进行映射。这里的关键是 AutoMapper 只创建一个 Select 投影,并由底层查询提供程序来适当地处理它。 AutoMapper 无法猜测支持或不支持什么,也不知道如何解析您的自定义方法,在 源类型 上,以及需要来自 SQL 的哪些数据。
首先询问 - 我将如何使用 EF 中的 Select 投影来完成此操作?然后 AutoMapper 将负责封装该投影。
【讨论】:
感谢您的回复,我知道 EF 无法解释它,我也不想让 EF 这样做,我也知道 automapper 只创建投影。我想知道我是否可以告诉 AM 为某些属性创建选择投影,而对于其他人告诉它不要投影它们,而是在查询完成并且我们有对象后映射它们。我可以在 DTO 上实现这些方法并在 getter 中调用它们,顺便说一句,我只是好奇。很棒的图书馆。 想一想——AutoMapper 怎么知道告诉 EF 哪些属性还需要返回?请记住 LINQ 投影的重点是更改 SQL 查询。我怎么知道要在原始 SQL 查询中包含什么,然后以某种方式保留它(请记住,原始源对象永远不会被您的 ORM 水合),在源对象上调用不存在的方法,然后映射它?您正在描述一种无法进行 LINQ 投影的场景。以上是关于Automapper 首先映射 EF 可投影属性,然后是其他属性的主要内容,如果未能解决你的问题,请参考以下文章
AutoMapper + EF Core:查询嵌套属性等于值的位置