在EF中使用left join而不是union与includeProperties

时间:2015-05-22 15:38:39

标签: sql-server linq entity-framework

当我在EF中包含多个属性时,它会生成' UNION ALL' SQL查询包含它们。如果我要包含3个属性,则运行速度几乎要慢3倍。 如果我使用3个左连接创建相同的查询,它表现得更好......

当linq生成查询时,是否可以使用左连接而不是联合?

如果不可能,使用union all的原因是什么,这似乎很慢?

1 个答案:

答案 0 :(得分:0)

首先,您可以执行left joins in LINQ to entities using DefaultIfEmpty

其次,如果导航属性为1:N (而不是1:1或1:0..1),那么使用3个连接将严重增加数据库的输出量这将降低性能,在这种情况下,运行一个查询来检索主要实体,然后基于第一个查询的ID的另外3个查询,使用.Future()扩展在单个数据库调用中运行,将导致更好的表现。

E.g。

var entities = context.Entities.AsQueryable().Where(...).ToList();
var ids = entities.select(e => e.Id).ToList();

var subEntities1Query = context.SubEntities1.AsQueryable().Where(se1 =>
    ids.Contains(se1.ParentId)).Future();
var subEntities2Query = context.SubEntities2.AsQueryable().Where(se2 =>
    ids.Contains(se2.ParentId)).Future();
var subEntities3Query = context.SubEntities3.AsQueryable().Where(se3 =>
    ids.Contains(se3.ParentId)).Future();

var subEntities1 = subEntities1Query.ToList();
var subEntities2 = subEntities2Query.ToList();
var subEntities3 = subEntities3Query.ToList();

foreach (var entity in entities)
{
    entity.SubEntities1 = subEntities1.Where(se1 =>
        se1.ParentId = entity.Id).ToList();
    entity.SubEntities2 = subEntities2.Where(se2 =>
        se2.ParentId = entity.Id).ToList();
    entity.SubEntities3 = subEntities3.Where(se3 =>
        se3.ParentId = entity.Id).ToList();
}