4

我有一种在 Linq 中经常使用的请求:

我需要一组数据,它们的 ID(或任何其他字段)位于项目列表中。这是一个繁重的要求,因为我有很多(使用过的) Include 来加载数据。

举个例子:

我有一张桌子,有这种结构:

Id; Name; Age; ...

这个表是几个用外键链接的表,我需要加载这些数据:汽车,公司,地址,...

现在我想检索具有特殊年龄的人的所有数据:

List<int> ages = new List<int>(){7,17,27,37,47,57,67,77,87};
using (MyDatabaseEntities context = new MyDatabaseEntities ())
{
   return context.Persons.Include("Car").Include("Company").Include("Address")
                 .Where(p=>ages.Contains(p.Age)).ToList();
}

问题是我的印象是 Linq 不知道我的“年龄”列表不会改变,然后下载完整的人员列表,以及他们的所有数据(汽车、公司、...)然后检查每个结果,如果它有正确的年龄。

所以。

  1. 我对吗?
  2. 如何避免这种情况?
4

2 回答 2

2

您可以像这样使用投影:

using (MyDatabaseEntities context = new MyDatabaseEntities())
{
   return context.Persons
    .Where(p => ages.Contains(p.Age))
    .Select(p => new {p, p.Car, p.Company, p.Address})
    .ToList();
}
于 2012-04-12T08:59:02.953 回答
1
  1. 我认为你错了:虽然你没有“枚举”你的查询(在你的情况下调用“ToList()”之前),但你没有“下载”任何东西。但是 sql 生成的代码可能不是那么高效。

你可以尝试调试你的代码:要么是 Sql Profiler,要么只是

var yourQuery = context.Persons.Include("Car").Include("Company").Include("Address")
                 .Where(p=>ages.Contains(p.Age));

var HarmQuery = context.Persons
    .Where(p => ages.Contains(p.Age))
    .Select(p => new {p, p.Car, p.Company, p.Address});


return yourQuery.ToList();

在“var query”上放置一个断点,并查看生成的 sql,复制它并在您的 db 目录中尝试,并检查两者的性能。

编辑: 如果您只需要“链接”实体的一部分属性,则投影肯定比包含更好:

.Select(p => new{p, p.Car.Name, p.Company.Id, p.Address.Street, p.Address.StreetNumber)

你不能用“includes”做什么,它检索包含实体的所有属性。

于 2012-04-12T09:36:23.400 回答