使用多个Include()/ ThenInclude()

时间:2019-05-23 01:00:54

标签: c# linq

我正在学习Linq查询,例如,每当我执行FirstOrDefault()ToList()时,有人告诉我,将向数据库发出请求。因此,我试图在Person DbSet中使用多个包含项来执行Linq,如下所示:

DbSet.Include(x => x.ManyToManyProperty)
     .ThenInclude(x => x.Company)
     .FirstOrDefault();

但是我想要的只是活跃的公司,但是要在FirstOrDefault()之前这样做(因此,我不会从数据库中带来不需要的东西)我做了Select,所以代码如下:

DbSet.Include(x => x.ManyToManyProperty)
     .ThenInclude(x => x.Company)
     .Select(x => new Person
          {
               ManyToManyProperty = x.ManyToManyProperty
                   .Where(c => c.Company.Active)
                        .Select(c => new ManyToManyProperty
                        {
                             Company = c.Company
                        }).ToList()
           }
     .FirstOrDefault();

所以上面的代码是问题所在,我在ToList()属性上执行ManyToMany,然后在FirstOrDefault() DbSet上执行Person,这将使Linq正常运行两次访问数据库,影响性能,而且我找不到只用FirstOrDefault()来获取我想要的所有信息的方法。

任何人都可以给我一个想法,怎么做吗?另外,如果对代码改进有任何建议,将不胜感激。

1 个答案:

答案 0 :(得分:-1)

使用Include通常不是一个好主意,主要是因为缺点多于优点。 您可能最终会从数据库中提取超出所需的数据,并且Include的性能取决于所包含的所有表中的行数(性能将与所有表的行数的乘积成正比)。

使用连接是一个更好的主意,这样您就可以准确地得到所需的内容。另请阅读有关延迟加载与快速加载的信息。那应该给你带来更好的画面。

如果要使用来自另一个查询的数据,请不要给它一个.ToList()。如果仅使用查询,则该查询采用IQueryable形式,并且可用作表本身(将其用于联接,分组依据,任何您想要的东西。它基本上转换为SELECT查询,可以在其他地方使用)。

此查询会有所帮助

var result = 
from ds in DbSet
join mtmp in ManyToManyProperty on ds.Property1 equals mtmp.Property1
join cmp in Company on mtmp.Property2 equals cmp.Property2
join p in Person on cmp.Property3 equals p.Property3
where p.IsActive //taking company as Active if it has active Persons
select cmp;

此查询将为您提供所有拥有活跃人员的公司。这可能是一家公司也可能不是一家公司,因此FirstOrDefault在这里不适用,因为该查询可能具有0到N个条目,而FirstOrDefault则适用于0到1个条目。

Ps。这只会打一次数据库。

编辑1: 阅读注释并查看代码后,这是一个最可能起作用的查询:

var result = (from mtmp in db.ManyToManyProperty
             join cmp in db.Company on mtmp.Company equals cmp.Id
             join p in db.Person in cmp.Id equals p.CompanyId
             where cmp.IsActive
             select p).ToList(); 
// This needs ToList because there can be many companies which are active.