C# EF:分组时包含属性

C# EF:分组时包含属性,c#,.net,entity-framework,C#,.net,Entity Framework,在一个大查询之后,我有以下分组类型: IQueryable<IGrouping<Type1, IGrouping<Type2, Type3>> result; var executedQuery = result .Include(a => a.Select(b => b.Select(c => c.Type3Property))) .ToList(); 我也尝试过SelectMany,但总是出现以下错

在一个大查询之后,我有以下分组类型:

    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,但未在用户代码中处理

其他信息:包含路径表达式必须引用 在类型上定义的导航属性。使用虚线路径 引用导航属性和集合的选择运算符 导航属性

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


当我搜索这个时,每个人似乎都能很好地使用Select来处理集合,我的情况有什么不对?

include应该总是可以转换为字符串重载IncludePropertyX。这意味着Select语句中lambda表达式的成员表达式必须包含寻址类型的属性。例如:

context.Companies.Include(c => c.Employees);
这里,Employees是在类型Company上定义的导航属性。EF所做的唯一事情是获取成员表达式c.Employees,然后在内部执行接受字符串参数的Include语句

现在,您将了解这不适用于lambda表达式:

b => b.Select(c => c.Type3Property))
它不包含属性,而是后续的Select语句,更不用说导航属性了

因此,您只能在IQueryable上直接使用Include,显然,tenty是EF类模型中的一种类型。而且,由于您在此处有分组,因此如果在应用查询形状后发生更改,则会忽略包含]。我认为在你的情况下,这意味着你甚至不能使用Include


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

作为我问题的解决方案,我在匿名对象的查询中显式选择了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();

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

这种形式的select语句看起来确实很奇怪。但是,它说该属性不是导航属性。实体是否正确配置?是的,它是EF从数据库自动生成的。该属性是虚拟的,如果我不使用分组,并且只选择Type3实体,Include工作得很好。谢谢,这确实很有用。“选择”仅用于导航属性集合。我同意你的观点,在大多数情况下,当事情编译并在运行时抛出异常时,对于那些曾经用于内存操作的事情,这真的很让人困惑。EF经常发生这种情况。