哪种方法可以关闭已编译的查询

时间:2010-07-16 08:15:37

标签: .net linq entity-framework compiled-query

我们知道你不能在编译的查询中添加像.Where().First()这样的额外子句,因为这会更改查询并强制重新编译。我想知道的是哪些方法可用于“关闭”编译的查询。

我知道大多数人都使用.AsEnumerable().ToList(),但其他哪些方法也可以使用?我可以使用.AsQueryable(),还是非操作?

哪个性能更好?我知道.AsEnumerable().ToList()快,但如果我想要IQueryable.AsEnumerable().AsQueryable().ToList()更好吗?

2 个答案:

答案 0 :(得分:7)

答案 1 :(得分:1)

  

哪些方法可用于“关闭”已编译的查询。

返回序列的方法使用延迟执行,除非方法类似于ToXYZWhereSelectTakeSkipGroupByOrderBy等属于此类。返回单个对象的方法会强制执行查询,例如FirstSingleToListToArrayToDictionaryToLookup,{{ 1}},Any等。请参阅此优秀主题:Linq - What is the quickest way to find out deferred execution or not?

  

我知道大多数人都使用.AsEnumerable()或.ToList(),但其他哪些方法也可以使用?我可以使用.AsQueryable(),还是这是一个无操作?

他们都不同。贾斯汀有一个宏大的解释。您可能还希望看到:What's the difference(s) between .ToList(), .AsEnumerable(), AsQueryable()?,它有一个很好的答案。


通常,您可以通过查看方法本身的名称来理解方法的语义。名为All的方法意味着它只会将输入作为返回。这可能涉及或不涉及返回新对象,但是以某种方式维护引用。例如,AsSomething只是对List<T>.AsEnumerable()进行强制转换(当然它在linq上下文中有更大的意义)。您可以将其强制转换回IEnumerable<T>并对其进行变异,以反映各处的变化。测试它:

List<T>

虽然看起来像var list = new List<int> { 1, 2 }; var enum = list.AsEnumerable(); var newlist = enum as List<string>; newlist.Add(3); //print enum.Count() -> 3 的方法,但是你会得到一个全新的对象,通常会被转换为其他东西。

ToSomething

让我们考虑一下linq背景之外的东西。 var list = new List<int> { 1, 2 }; var newlist = list.ToList(); newlist.Add(3); //print list.Count -> 2 导致新的字符串表示(字符串无论如何都是不可变的,因此有点无意义)。一个有趣的语义是object.ToString()返回一个新的List<T>.AsReadonly实例,但是改变它之外的列表也会改变ReadOnlyCollection<T>的内部列表,因此命名为ReadOnlyCollection<T>

AsReadonly