【问题标题】:Linq Lambda GroupJoin and ToList()Linq Lambda GroupJoin 和 ToList()
【发布时间】:2020-05-25 18:20:56
【问题描述】:

我在实体框架中使用了一些 GroupJoin,以便为“a”主节点聚合“b”元素列表。我的问题是,一旦我返回来自 db 的 query.ToList() 对象,我就无法提取 IEnumerable 元素,因为我不在它们的上下文中。我想放一个.ToList()"bList.Tolist()" 但我认为那里的tolist会导致整个查询立即执行,性能很差。你能帮帮我吗?

class Result
{
  IEnumerable<string> Strings { get; set; }
}
using (var context = new TicketingContext())
            {
                var query = context.A.GroupJoin(context.B,
                    a => a.IDA,
                    b => b.IDA,
                    (a, bList) => new { a, Result = new Result { Strings = bList } }
                    )
                var res = query.ToList();
            }

我的问题是,如果我在下面的代码中添加一个 tolist(),整个查询将被执行吗?有转机吗?

using (var context = new TicketingContext())
            {
                var query = context.A.GroupJoin(context.B,
                    a => a.IDA,
                    b => b.IDA,
                    (a, bList) => new { a, Result = new Result { Strings = bList.**ToList()** } }
                    )
                var res = query.ToList();
            }

【问题讨论】:

  • 您能否详细说明“我无法导航 IEnumerable 元素,因为它们不是具体的”?你想做什么?此外,您的示例使用Join 而不是GroupJoin
  • 您好 J. 感谢您的回复。问题是在使用上下文之外我不能做 obj.Result.Strings.ToList() 因为它是一个 IEnumerable。只有在内部使用我才能做到。为了避免这个问题,我的解决方案是...... a, Result = new Result {Strings = bList.ToList()} 但我不确定它在性能方面是否是一个好的解决方案。
  • 嗯,好的。您不能在上下文之外执行ToList 的原因并不是因为它本身就是IEnumerableIEnumerable 是一个简单定义迭代器的接口,可以通过多种方式实现。使用 Entity Framework 时,该实现是在数据库上执行 SQL 查询,但是一旦在您的 using 块之外,数据库连接就会被释放。
  • 您希望如何在不立即执行查询的情况下处理查询结果? LINQ to a database 必须始终返回整个查询才能使用结果。

标签: c# entity-framework linq lambda


【解决方案1】:

原因

因为在using() 之外,dbContext 被处置。所以你需要.ToList()如你所愿。

 using (var context = new TicketingContext())
 {
     var res = context.A.GroupJoin(context.B,
                a => a.IDA,
                b => b.IDA,
                (a, bList) => new { a, Result = new Result { Strings = bList.ToList() } }
                ).ToList();
 }

【讨论】:

  • 感谢 Phong 的帮助。我知道在上下文之外处理了对象,但我担心您添加的“ToList()”。我认为您编写的代码将执行 2 个查询而不是 1 个。
  • 在我看来,EF 已经通过组合所有查询来一次运行进行了优化。所以你不必担心。
  • @MattiaP。这实际上取决于您使用的是哪个版本的 EF:EF Core 2.x、EF Core 2.2、EF Core 3.x、EF 6.x。
  • @NetMage 感谢您的回复,我正在使用 EF Core,关键是我找不到有关在 GroupJoin 中执行 ToList() 时会发生什么的文档,我不知道是什么部分查询将被执行。我知道在普通的 EF iqueryable 中 ToList() 将立即执行整个查询,我试图了解一个复杂的查询是否具有 n 个连接和 m 个 groupjoins EF 将具有良好的性能,或者我正在使用 ef 不是正确的方式。
  • @MattiaP。 EF Core 的版本很重要。 GroupJoin 与任何其他构造没有什么不同,放置 ToList 将立即完全评估查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多