我应该在 linq-to-sql 查询中使用什么集合?可查询与可枚举与列表

What collection should I use in a linq-to-sql query? Queryable vs Enumerable vs List

想象一下 类:

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Underage
{
    public int Age { get; set; }
}

然后我做了这样的事情:

var underAge = db.Underage.Select(u => u.Age)   .ToList()/AsEnumerable()/AsQueryable() 

var result = db.Persons.Where(p => underAge.Contains(p.Age)).ToList();

最好的选择是什么?如果我调用 ToList(),项目将被检索一次,但如果我选择 AsEnumerableAsQueryable,每次从 Where() 中的数据库中选择一个人时,它们都会被执行(如果这就是它的工作原理,我不太了解数据库在后台的作用)?

此外,Underage 包含数千条记录与少量记录是否存在更大差异?

您应该使用连接来获取数据。

var query = (from p in db.Persons
             join u in db.Underage
              on u.Age equals p.Age
             select p).ToList();

如果您在上面的查询中不使用 .ToList(),则它 return IEnumerable 类型的 Person 和实际数据将在您使用该对象时获取。

根据您要使用的场景,ToList()、AsEnurmeable 和 Querable 都一样好。对于你的情况,ToList 对我来说看起来不错,因为你只想获取未成年人员的列表

None.

你肯定不想在这里使用 ToList(),因为那样会将所有匹配值加载到内存中,然后用它来为 result 编写具有大量 IN (…) 子句。当您真正想要的只是首先从数据库中获取匹配值时,这是一种浪费,查询类似于

SELECT *
FROM Persons
WHERE EXISTS(
  SELECT NULL FROM 
  FROM Underage
  WHERE Underage.age = Persons.age
)

AsEnumerable() 通常会阻止对数据库进行操作,尽管提供者可能会检查来源并撤消 AsEnumerable() 的影响。 AsQueryable() 很好,但在这种情况下实际上没有做任何事情。

你不需要其中任何一个:

var underAge = db.Underage.Select(u => u.Age);

var result = db.Persons.Where(p => underAge.Contains(p.Age)).ToList();

(就此而言,请检查您是否确实需要最后一行中的 ToList();如果您要对其进行进一步查询,它可能会伤害到他们,如果您只是枚举结果是浪费时间和内存,如果你要存储它们或做很多在 Linq 中无法完成的内存操作,那会更好)。

如果您将第一个查询保留为

  var underage = db.Underage.Select(u => u.Age);

它将是 IQueryable 类型,并且不会对您的数据库执行 ping 操作(实际上称为延迟执行)。一旦您真正想要执行对数据库的调用,您可以使用贪心运算符,例如 .ToList()、.ToArray()、.ToDictionary()。这将为您的结果变量提供一个 IEnumerable 集合。

See linq deferred execution