想象一下以下几个类:
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()
的数据库中选择一个人时,都会执行这些项目({1}}如果它是如何工作的,我不太了解数据库在后台做了什么?)
当Underage包含数千条记录与少量记录时,还有更大的差异吗?
答案 0 :(得分:2)
无。
你绝对不希望ToList()
在这里,因为这会将所有匹配的值加载到内存中,然后用它来编写result
的查询,这个查询具有大量IN (…)
其中的1}}子句。当你真正想要的是首先从数据库中获取匹配值时,这是一种浪费,其查询类似于
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()
;如果你要对它进行进一步的询问,它可能会伤害他们,如果你&# 39;如果您要存储它们或者做很多内存操作而无法在Linq中完成,那么只需要列举结果就会浪费时间和记忆。 #39;将会变得更好。)
答案 1 :(得分:2)
如果您将第一个查询保留为
var underage = db.Underage.Select(u => u.Age);
它将是IQueryable类型,它不会ping你的数据库(acutaly称为延迟执行)。一旦你真的想要执行对数据库的调用,你可以使用贪婪的运算符,如 .ToList(),. ToArray(),. ToDictionary()。这将为您的结果变量提供一个IEnumerable集合。
答案 2 :(得分:1)
您应该使用join来获取数据。
var query = (from p in db.Persons
join u in db.Underage
on u.Age equals p.Age
select p).ToList();
如果您在上面的查询中没有使用.ToList()
,则会返回Person类型的IEnumerable
,并且在您使用该对象时将获取实际数据。
根据您要使用的场景,所有内容同样优秀的ToList(),AsEnurmeable和Querable。对于你的情况ToList看起来对我很好,因为你只想获取有未成年人的人员名单