Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在linq到sql查询中应该使用什么集合?可查询vs可枚举vs列表_C#_Linq_Linq To Sql_Linq To Entities - Fatal编程技术网

C# 在linq到sql查询中应该使用什么集合?可查询vs可枚举vs列表

C# 在linq到sql查询中应该使用什么集合?可查询vs可枚举vs列表,c#,linq,linq-to-sql,linq-to-entities,C#,Linq,Linq To Sql,Linq To Entities,想象一下以下几类: 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()

想象一下以下几类:

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()
中的数据库中选择一个人时,都会执行这些项目(如果是这样,我不知道数据库在后台做了什么)


当未成年人将包含数千条记录而不是少量记录时,是否存在更大的差异?

您应该使用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()、asenumeable和query。就您的情况而言,托利斯特对我来说很好,因为您只想获取未成年人名单

您肯定不希望在这里使用
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集合


对其进行了编辑,但我想知道在上面的示例中,使用Linq表达式时,什么是最好的。一定有区别。如果我将其设置为IQueryable,它是将该查询“附加”到第二个查询,还是像我使用ToList()时那样执行单独的查询?如果
未成年人中存在任何重复的年龄,则加入将是不正确的。要匹配问题中的查询结果,您必须将其作为已知的不变量,即不存在重复的年龄,或者对此使用
Distinct()
。因此,当我调用第二行中的ToList时,我的程序将只执行一个查询?是的,执行一次,执行与上面显示的SQL相当的操作,并制作一份清单。但是,如果您只是对它执行了
foreach
,它将执行SQL,然后在每个对象出现时使用它们,这通常会更快。如果您没有执行
ToList()
foreach
,那么您将有另一个可以进一步组合的查询。例如,通过添加另一个
Where()
或调用类似于
Count()
的方法,大部分工作都可以在数据库中完成,而不是将其全部收集起来。谢谢!我将研究foreach,98%的时间里从未将其用于Linq98,如果可能的话,linq的最终结果应该是调用聚合(
Count()
Max()
或其他给出单个结果的东西),或者直接通过结果调用
foreach
。只有在确实需要集合时才调用集合生成方法(
ToList()
ToDictionary()
ToLookup()
)。也有一些例外情况(特别是,
GroupBy
的某些用法在内存中会更有效),但默认情况下,每次都会尽可能少地放入内存。一般规则是尽可能长时间地保持对象尽可能接近原始对象。DbSet>IQueryable>IEnumerable>List/Array。只有当你有理由需要低一点的而高一点的不起作用时,才使用低一点的。谢谢!这样保留代码和添加.AsQueryable()之间有区别吗?我认为,添加
AsQueryable()
不仅会在以后查看代码并想知道它的用途时混淆问题。