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

时间:2017-08-28 16:11:48

标签: c# linq union

我尝试在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<T>。但是我在尝试获得结果时遇到错误。

  

指定的LINQ表达式包含对查询的引用   与不同的背景相关联。

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

如果你想要&#39;以这种方式执行你的工会,你必须在本地记忆中做到这一点。 Enumerable.AsEnumerable会将您的数据带到本地内存,可以与本地内存中的其他数据结合使用。

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

顺便说一句,如果您经常使用这种联合方式,请考虑使用工作单元模式将其放入一个工作单元。

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

答案 1 :(得分:0)

您是否可以创建统一类并在每个查询中填充select子句中的所有属性,然后执行联合。