指定映射表达式 - 以便它与 LINQ EF 和投影一起使用
本文关键字:EF LINQ 投影 一起 映射 表达式 | 更新日期: 2023-09-27 18:32:00
我有很多这样的代码:
Mapper.CreateMap<DbModel.Kabinetas, Kabinetas>()
.ForMember(n => n.Numeris, m => m.MapFrom(f => f.Numeris ?? ""))
.ForMember(m => m.MetaDuomenys, y => y.MapFrom(s =>
new MetaDuomenys
{
ArPanaikintas = s.SecLevel == null ? (bool?)null : s.SecLevel == 2 ? true : false,
PakeitimuData = s.PakeitimuData
}))
;
Mapper.CreateMap<DbModel.Specialybe, Specialybe>()
.ForMember(i => i.Istaigos, y => y.Ignore())
.ForMember(m => m.MetaDuomenys, y => y.MapFrom(s =>
new MetaDuomenys
{
ArPanaikintas = s.SecLevel == null ? (bool?)null : s.SecLevel == 2 ? true : false,
PakeitimuData = s.PakeitimuData
}))
;
其中带有"MetaDuomenys"(又名元数据)的部分一遍又一遍地重复它。
我希望能够写出这样的东西:
Expression<Func<BaseWMeta, MetaDuomenys>> expr = p =>
new MetaDuomenys
{
ArPanaikintas = p.SecLevel == null ? (bool?)null : p.SecLevel == 2 ? true : false,
PakeitimuData = p.PakeitimuData
};
Mapper.CreateMap<Expression<Func<BaseWMeta, MetaDuomenys>>, MetaDuomenys>();
然后像这样使用它:
.ForMember(m => m.MetaDuomenys, y => y.MapFrom(s => expr))
所以当我需要数据库中的单个对象时,这有点有效,但如果我尝试像这样投影它:
db.Kabinetai.Project().To<KabinetasDC>()
我收到以下异常:
<m:internalexception>
<m:message>
The LINQ expression node type 'Lambda' is not supported in LINQ to Entities.
</m:message>
<m:type>System.NotSupportedException</m:type>
你需要项目使用:
Mapper.CreateMap<BaseWMeta, MetaDuomenys>()
.ProjectUsing(p =>
new MetaDuomenys
{
ArPanaikintas = p.SecLevel == null ? (bool?)null : p.SecLevel == 2 ? true : false,
PakeitimuData = p.PakeitimuData
});
ProjectUsing 类似于 ConvertUsing(定义 2 种类型之间的映射,包括 Func),只是你得到一个表达式,而不仅仅是一个 Func。然后,每当自动映射程序找到自定义投影的源/目标类型时,此表达式都会传递到选择投影。
配置的其余部分是:
Mapper.CreateMap<DbModel.Kabinetas, Kabinetas>()
.ForMember(n => n.Numeris, m => m.MapFrom(f => f.Numeris ?? ""));
Mapper.CreateMap<DbModel.Specialybe, Specialybe>()
.ForMember(i => i.Istaigos, y => y.Ignore());
你试过ValueResolver<TSource, TDestination>
吗?
一个简单的例子(字符串 id 到 mongodb objectid):
public class UserIdResolver : ValueResolver<UserViewModel, ObjectId>
{
protected override ObjectId ResolveCore(UserViewModel source)
{
ObjectId objectId = new ObjectId();
if (!string.IsNullOrEmpty(source.Id))
{
objectId = new ObjectId(source.Id);
}
return objectId;
}
}
映射是这样的:
Mapper.CreateMap<UserViewModel, UserEntity>()
.ForMember(dest => dest.Id, src => src.ResolveUsing<UserIdResolver>());