指定映射表达式 - 以便它与 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>

指定映射表达式 - 以便它与 LINQ EF 和投影一起使用

你需要项目使用:

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>());