【问题标题】:Assign Mapped Object to Expression Result in LINQ to Entities在 LINQ to Entities 中将映射对象分配给表达式结果
【发布时间】:2020-01-03 16:15:45
【问题描述】:

我有以下子对象,我们使用表达式将我们的“实体”映射到我们的“域”模型。我们在专门调用我们的 ChildRecordService 方法 GetChild 或 GetChildren 时使用它:

    public static Expression<Func<global::Database.Models.ChildRecord, ChildRecord>> MapChildRecordToCommon = entity => new ChildRecord
    {
        DateTime = entity.DateTime,
        Type = entity.Type,
    };

    public static async Task<List<ChildRecord>> ToCommonListAsync(this IQueryable<global::Database.Models.ChildRecord> childRecords)
    {
        var items = await
            childRecords.Select(MapChildRecordToCommon).ToListAsync().EscapeContext();

        return items;
    }

    public async Task<List<ChildRecord>> GetChildRecords()
    {
        using (var uow = this.UnitOfWorkFactory.CreateReadOnly())
        {
            var childRecords= await uow.GetRepository<IChildRecordRepository>().GetChildRecords().ToCommonListAsync().EscapeContext();

            return childRecords;
        }
    }

所以一切正常。但是,我们还有另一个对象是该子对象的父对象,在某些情况下,我们还希望在物化和映射过程中获取子对象。

换句话说,标准对象看起来是这样的:

    private static Expression<Func<global::Database.Models.Plot, Plot>> MapPlotToCommonBasic = (entity) => new Plot
    {
        Id = entity.Id,
        Direction = entity.Direction,
        Utc = entity.Utc,
        Velocity = entity.Velocity,
    };

但是,我还想映射 Plot.ChildRecord 属性,使用我已经创建的表达式 MapChildRecordToCommon。我做了第二个表达式来测试一下:

    private static Expression<Func<global::Database.Models.Plot, Plot>> MapPlotToCommonAdvanced = (entity) => new Plot
    {
        ChildRecord = MapChildRecordToCommon.Compile() (entity.ChildRecord)
    };

这失败了:

System.NotSupportedException
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

有没有办法重用我现有的 ChildRecord 表达式,在 Plot 对象上实现 ChildRecord 的对象(即一对一/单数而不是多个)?我认为我的问题是因为只有一个对象并且无法使用 .Select(Map) 方法。我不太擅长表达,已经碰壁了。

作为参考,“Plot”对象上实际上最多还有 5 或 6 个其他子对象,我也想为其制作表达式。

【问题讨论】:

    标签: entity-framework linq expression


    【解决方案1】:

    我通过使用第三方库 LinqKit 解决了这个问题。

    该库允许使用 2 种方法,.AsExpandable()(它允许表达式正确编译并按照我的理解被调用)和 .Invoke() 作为表达式的扩展方法,而不是调用 Expression .Invoke(你的表情)。为了以防万一,我添加了一个空检查。

    我的代码现在如下所示:

    public static async Task<List<Plot>> ToCommonListAsync(this IQueryable<global::Database.Models.Plot> plots)
    {
        var items = await
            plots.AsExpandable().Select(MapPlotToCommon).ToListAsync().EscapeContext();
    
        return items;
    }
    
    private static Expression<Func<global::Database.Models.Plot, Plot>> MapPlotToCommon = (entity) => new Plot
    {
        Id = entity.Id,
        Direction = entity.Direction,
        Utc = entity.Utc,
        Velocity = entity.Velocity,
        ChildRecord = entity.ChildRecord != null ? MapChildRecordToCommon.Invoke(entity.ChildRecord) : default
    };
    
    public static Expression<Func<global::Database.Models.ChildRecord, ChildRecord>> MapChildRecordToCommon = entity => new ChildRecord
    {
        DateTime = entity.DateTime,
        Type = entity.Type,
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2016-04-17
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      相关资源
      最近更新 更多