我应该在 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()
,项目将被检索一次,但如果我选择 AsEnumerable
或 AsQueryable
,每次从 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 集合。
想象一下 类:
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()
,项目将被检索一次,但如果我选择 AsEnumerable
或 AsQueryable
,每次从 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 集合。