【问题标题】:EF Core conditional includeEF Core 条件包含
【发布时间】:2021-07-12 04:17:14
【问题描述】:

我有一个公司实体与订单实体具有一对多关系。

订单可以是匿名的,在这种情况下,查询订单时不应加载相关公司。

当前格式创建一个 IQueryable,然后向其添加过滤器,如下所示:

IQueryable<Order> queryable = ...
...
if (includeCompany is not null and true)
    {
        queryable = queryable.Include(o => o.Company);
    }

if (includeAddress is not null and true)
...

我能否将包含条件设置为在单个查询中使用订单的 isAnonymous 布尔值,以便仅包含非匿名订单的公司实体?

【问题讨论】:

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


    【解决方案1】:

    很遗憾,没有。过滤后的Include 不能应用于引用导航属性,只能应用于集合。

    你将不得不求助于一个丑陋的解决方法:

    context.Orders.Select(o => new 
    { 
        o, 
        Company = o.Order.IsAnonymous
            ? null
            : o.Company
    })
    .AsEnumerable()
    .Select(x => x.o)
    

    现在非匿名订单将具有 Company 引用,因为 EF 通过关系修复填充它们。

    AsEnumerable 导致 EF 构建整个匿名类型。没有它,最后的 Select 是表达式的一部分,EF 得出结论,可以完全忽略这些公司,因为它不会在最终结果中“看到”它们。

    【讨论】:

    • 鉴于(出于明显的 DRY 原因)每个相关数据加载“开箱即用”方法的内部实现都以一种或另一种方式依赖/使用导航修复,我不会认为它“丑陋”,只是令人讨厌它不是由框架提供的。但如果是这样,具体化枚举器的作用与此处显示的几乎相同,只是将其隐藏在外部。
    【解决方案2】:

    当然,queryable = queryable.Include(o =&gt; o.Company).where(o =&gt; o.isAnonymous);
    queryable是IQueryable,可以加条件并且没有访问数据库。

    【讨论】:

    • 这不起作用,因为它只会返回匹配 where 条件的订单。我想做的是退回所有订单,但只包括非匿名的相关公司。
    猜你喜欢
    • 2020-03-19
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    相关资源
    最近更新 更多