【问题标题】:How generate single UNION query in LINQ?如何在 LINQ 中生成单个 UNION 查询?
【发布时间】:2017-08-28 16:11:47
【问题描述】:

我尝试在 LINQ 中生成 UNION 查询:

var a = _aReposytory.GetAll().OrderByDescending(t => t.EndT).Take(100);
var b = _bReposytory.GetAll().OrderByDescending(t => t.EndT).Take(100);
var c = _cReposytory.GetAll().OrderByDescending(t => t.EndT).Take(100);
var d = _dReposytory.GetAll().OrderByDescending(t => t.EndT).Take(100);

var result = a.Cast<IEntity>().Union(b.Cast<IEntity>())
                .Union(c.Cast<IEntity>()).Union(d.Cast<IEntity>()).ToList();

所有实体都继承IEntity接口并具有相同的字段。 _aReposytory.GetAll()_bReposytory.GetAll() 等返回 IQueryable&lt;T&gt;。但是在尝试获取结果时出现错误。

指定的 LINQ 表达式包含对以下查询的引用 与不同的上下文相关联。

当我使用以下UNION 逻辑时,它是有效的。但它是四个查询执行。

var union = new List<ICdcEntity>(a);
                union.AddRange(b);
                union.AddRange(c);
                union.AddRange(d);

如何在 LINQ 中生成单个 UNION 查询?

【问题讨论】:

  • _aReposytory.GetAll()(和其他方法)是否返回 IEnumerable&lt;T&gt;IQueryable&lt;T&gt;
  • 你的错误信息很清楚。每个上下文都从您的 Linq 查询生成 SQL,但您不能从 4 个不同的上下文生成单个 SQL 语句。即使你可以,它仍然会导致四个查询。
  • 我相信这里的答案正确地解释了你的错误:stackoverflow.com/a/38627389/3042383

标签: c# linq union


【解决方案1】:

如果您使用实体框架(或类似的东西)从数据库中获取数据,您可以选择让您的数据库执行查询,并只返回您想要的数据,或者您可以选择获取比您更多的数据想要你的最终结果并在本地内存中过滤它。

第一个完成AsQueryable,后者完成AsEnumerable

虽然Queryable.Union存在,但只能合并同一个数据库中的表。

您正在对不同的存储库执行查询,这意味着它们的数据可能位于不同的数据库中。

如果您想以这种方式执行联合,则必须在本地内存中执行。 Enumerable.AsEnumerable 会将您的数据带到本地内存中,在那里它可以与本地内存中的其他数据合并。

但是,如果您的数据确实应该在同一个数据库中,那么如果您可以执行查询 AsQueryable,效率会高得多。您应该确保您的存储库使用相同的DbContext 实例。在这种情况下,您应该能够在数据库 sid 上执行查询。

顺便说一下,如果你经常做这种联合工作,可以考虑使用工作单元模式将其放入一个工作单元中。

更多信息:Implementing the repository pattern and unit-of-work patterns

【讨论】:

    【解决方案2】:

    能否创建一个统一的类,在每个查询中填充select子句中的所有属性,然后做一个Union。

    【讨论】:

      猜你喜欢
      • 2012-04-19
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多