我尝试在 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
查询?
如果使用实体框架(或类似内容(从数据库提取数据,则可以选择让数据库执行查询,并仅返回所需的数据,也可以选择提取比最终结果中所需的更多的数据,并将其筛选在本地内存中。
前者AsQueryable
完成,后者AsEnumerable
完成。
尽管 Queryable.Union 存在,但它只能合并同一数据库中的表。
您正在不同的存储库上执行查询,这意味着它们的数据可能位于不同的数据库中。
如果你想以这种方式执行联合,你必须在本地内存中执行此操作。Enumerable.AsEnumerable 会将您的数据带到本地内存,在那里它可以与本地内存中的其他数据合并。
但是,如果您的数据确实应该位于同一数据库中,那么如果可以执行查询 AsQueryable,效率会高得多。您应确保您的存储库使用相同的DbContext
实例。在这种情况下,您应该能够在数据库 sid 上执行查询。
顺便说一下,如果你经常做这种联合运动,请考虑使用工作单元模式将其放入一个工作单元中。
详细信息:实现存储库模式和工作单元模式
您能否创建一个统一的类并填充每个查询中 select 子句中的所有属性,然后执行联合。