Linq:如何使用表/列表作为参数来优化请求?

时间:2012-04-12 08:38:22

标签: c# database linq entity-framework join

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

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

这是一个例子:

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

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. 如何避免这种情况?

2 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:1)

  1. 我认为你错了:虽然你没有“枚举”你的查询(在你的情况下调用“ToList()”之前),你不会“下载”任何东西。但是sql生成的代码可能不是那么高效。
  2. 您可以尝试调试代码: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 directy中尝试它,并检查两者的性能。

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

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

    使用“includes”无法做到的事情,它会检索所包含实体的所有属性。