【问题标题】:EF: Include property on groupingEF:在分组中包含属性
【发布时间】:2018-02-24 22:01:59
【问题描述】:

在大查询后我有以下分组类型:

    IQueryable<IGrouping<Type1, IGrouping<Type2, Type3>> result;
    var executedQuery = result
       .Include(a => a.Select(b => b.Select(c => c.Type3Property)))
       .ToList();

我也尝试过 SelectMany,但我总是收到以下错误:

“System.ArgumentException”类型的异常发生在 EntityFramework.dll 但未在用户代码中处理

附加信息:包含路径表达式必须引用 在类型上定义的导航属性。使用虚线路径 参考导航属性和用于集合的 Select 运算符 导航属性。

我不能在查询中使用 Include,因为它在分组之前不起作用。

当我搜索此内容时,似乎每个人都认为 Select 可以很好地处理集合,我的情况有什么问题?

【问题讨论】:

  • 这种形式的选择语句确实看起来很奇怪。但是,它说该属性不是导航属性。实体配置正确吗?
  • 是的,它是 EF 从数据库中自动生成的。该属性是虚拟的,如果我不使用分组,并且只选择 Type3 实体,Include 就可以了。

标签: c# .net entity-framework


【解决方案1】:

包含应始终可转换为字符串重载Include("PropertyX")。这意味着Select 语句中的 lambda 表达式的成员表达式必须包含寻址类型的属性。例如:

context.Companies.Include(c => c.Employees);

这里,Employees定义在类型上的导航属性 Company。 EF 唯一要做的就是获取成员表达式c.Employees,然后在内部执行接受字符串参数的Include 语句。

现在您会明白这不适用于您的 lambda 表达式:

b => b.Select(c => c.Type3Property))

它不包含属性,而是后续的Select 语句,更不用说导航属性

所以你只能在IQueryable&lt;TEntity&gt; 上直接使用Include(显然,TEntity 是 EF 类模型中的一个类型)。 而且,由于您在这里有分组,Includes 在应用后查询形状发生变化时会被忽略](Why doesn't Include have any effect?)。我认为在你的情况下,这意味着你甚至不能使用Include

旁注:在我自己的代码中,我总是竭尽全力避免滥用。比如,“我们有这个属性X,让我们用它作为一个信号......”无论如何。并且引入了一个棘手的依赖和副作用的来源。我可以理解 EF 决定滥用 lambda 表达式来实现编译时可检查的 Include 重载,但这引起了难以置信的混乱。只允许使用 lambdas 做的所有事情的 1%。其他 99% 编译但抛出运行时异常。

【讨论】:

  • 谢谢,这确实有意义。 Select 仅用于导航属性集合。我同意你的观点,当事情编译并在运行时抛出异常时,大多数时候,对于曾经用于内存操作的事情来说,这真的很令人困惑。 EF 经常发生这种情况。
【解决方案2】:

作为我的问题的解决方案,我在匿名对象的查询中明确选择了 Type3 的属性:

result.Select(g => new
        {
            Key = g.Key,
            Value = g.SelectMany(e => e.Select(x=> new
            {
                RootObject = x,
                Child1= x.prop1,
                Childe2 = x.prop2
            }))
        }).ToList();

这实际上加载了孩子,即使我只使用根对象。它不漂亮,但它解决了我的问题。

【讨论】:

    猜你喜欢
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多