实体框架核心选择外部联接

时间:2018-07-11 08:10:38

标签: entity-framework asp.net-core entity-framework-core

是否有一种简单的方法可以在EF Core的select表达式中包含可为空的导航?

我的模特看起来像这样

public class RootVO
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Description { get; set; }

    public int? RelationId { get; set; }
    [ForeignKey(nameof(RelationId))]
    public RelationVO Relation { get; set; }
}

public class RelationVO
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Property1 { get; set; }

    [Required]
    [StringLength(200)]
    public string Property2 { get; set; }

    public ICollection<RootVO> RootRelations { get; set; }
}

当我加载数据时,我只想选择某些类型的属性。目前,我的表情如下:

Expression<Func<RootVO, RootVO>> selectExpr = m => new RootVO
{
    Id = m.Id,
    Description = m.Description,
    Relation = m.Relation != null ? new RelationVO
    {
        Id = m.Relation.Id,
        Property1 = m.Relation.Property1                        
    } : null
};

var result = context.Roots.Select(selectExpr).ToList();

有没有更简单的方法来处理关系选择?

修改

也许这里的一些背景会有所帮助:

我有一个巨大的对象,它具有许多列和关系,有些具有内部关系,有些具有外部联接。 UI上的数据网格可以访问此查询,该数据网格可以具有动态列,具体取决于用户选择。为了提高性能,我编写了一个类,该类将根据所选列动态构建选择表达式。目前它正在工作,但是由于空引用例外,当外部联接为空时,我遇到了麻烦。

表达式的调试视图如下所示:

.New IVA.Core.Data.Models.StockMovementLogVO(){
    SequenceNo = $m.SequenceNo,
    PostingPeriodId = $m.PostingPeriodId,
    TransactionDate = $m.TransactionDate,
    FinancialYear = $m.FinancialYear,
    FinancialYearPeriod = $m.FinancialYearPeriod,
    VoucherDate = $m.VoucherDate,
    ItemQuantity = $m.ItemQuantity,
    BuCode = $m.BuCode,
    LocationStructure = .New IVA.Core.Data.Models.LocationStructureVO(){
        Id = ($m.LocationStructure).Id,
        Description = ($m.LocationStructure).Description
    },
    BookingType = .New IVA.Core.Data.Models.BookingTypeVO(){
        Id = ($m.BookingType).Id,
        Description = ($m.BookingType).Description
    },
    PartnerStockLocationType = .New IVA.Core.Data.Models.StockLocationTypeVO(){
        Id = ($m.PartnerStockLocationType).Id,
        Description = ($m.PartnerStockLocationType).Description
    },
    StockLocationType = .New IVA.Core.Data.Models.StockLocationTypeVO(){
        Id = ($m.StockLocationType).Id,
        Description = ($m.StockLocationType).Description
    }
}

StockLocationType和PartnerStockLocationType是外部联接,如果为空,则查询将无法执行。

1 个答案:

答案 0 :(得分:0)

我现在已经更改了表达式生成器,它将通过包含空引用检查来处理外部联接。表达式现在看起来像这样:

.New IVA.Core.Data.Models.StockMovementLogVO(){
    SequenceNo = $m.SequenceNo,
    PostingPeriodId = $m.PostingPeriodId,
    TransactionDate = $m.TransactionDate,
    FinancialYear = $m.FinancialYear,
    FinancialYearPeriod = $m.FinancialYearPeriod,
    VoucherDate = $m.VoucherDate,
    ItemQuantity = $m.ItemQuantity,
    BuCode = $m.BuCode,
    LocationStructure = .New IVA.Core.Data.Models.LocationStructureVO(){
        Id = ($m.LocationStructure).Id,
        Description = ($m.LocationStructure).Description
    },
    BookingType = .New IVA.Core.Data.Models.BookingTypeVO(){
        Id = ($m.BookingType).Id,
        Description = ($m.BookingType).Description
    },
    PartnerStockLocationType = .If ($m.PartnerStockLocationType != null) {
        .New IVA.Core.Data.Models.StockLocationTypeVO(){
            Id = ($m.PartnerStockLocationType).Id,
            Description = ($m.PartnerStockLocationType).Description
        }
    } .Else {
        null
    },
    StockLocationType = .If ($m.StockLocationType != null) {
        .New IVA.Core.Data.Models.StockLocationTypeVO(){
            Id = ($m.StockLocationType).Id,
            Description = ($m.StockLocationType).Description
        }
    } .Else {
        null
    }
}

修改

如果对外观有任何疑问,我会在使用该类的地方创建一个存储库。

https://github.com/NQuirmbach/DynamicQueryBuilder