C# 何时执行返回IQueryable的编译查询?

C# 何时执行返回IQueryable的编译查询?,c#,.net,linq-to-sql,C#,.net,Linq To Sql,好的,我需要一个精神检查 我编译了一个查询,在执行时返回IQueryable 在下面的示例中,应该在哪一行对数据库执行查询? 101 IQueryable<T> results = MyCompiledQuery(MyDataContext); 102 List<T> final = (from t in result 103 where t.ID > 5 104 select t).ToList&

好的,我需要一个精神检查

我编译了一个查询,在执行时返回IQueryable

在下面的示例中,应该在哪一行对数据库执行查询?

101 IQueryable<T> results = MyCompiledQuery(MyDataContext);
102 List<T> final = (from t in result
103                  where t.ID > 5
104                  select t).ToList<T>();
101 IQueryable results=MyCompiledQuery(MyDataContext);
102列表最终=(从结果中的t开始
103其中t.ID>5
104选择t).ToList();
下面是我如何定义已编译查询的

 public static Func<MyDataContext, IQueryable<Widget>> MyCompiledQuery=
        CompiledQuery.Compile<MyDataContext, IQueryable<Widget>>(
                      (MyDataContext db) =>
                      from w in db.Widgets
                      where ((w.Type == WidgetType.Atype ||  //Widget.Atype is a Linq to Sql object, that I've defined statically
                              w.Type == WidgetType.Btype ||  //See above comment
                              w.Type == WidgetType.Ctype ) && //See above comment
                              w.Location == WidgetLocation.Domestic)  //Samething applies here
                        select euc);
公共静态函数MyCompiledQuery=
CompiledQuery.Compile(
(MyDataContext db)=>
来自db.Widgets中的w
其中((w.Type==WidgetType.Atype | |//Widget.Atype是我静态定义的Linq到Sql对象
w、 Type==WidgetType.Btype | |//参见上面的注释
w、 Type==WidgetType.Ctype)&&&//参见上面的注释
w、 Location==WidgetLocation.homonal)//此处适用相同的设置
选择euc);
有关更多讨论,请参阅:

“在进行列表转换时,在第104行。”

这个答案是不正确的。我们在第101行调用存储在MyCompiledQuery变量中的委托,该委托返回已编译查询的结果,而不是查询本身。

它在第104行执行(当您调用ToList()时)


编译后的查询是在编译时只转换一次到TSQL的查询,而不是执行前的每次转换。

这称为延迟执行。

你可以在上面读到一篇好文章。

此查询在第101行执行。我通过执行SQL探查器跟踪来验证它。我猜这是因为它是一个编译过的查询


您在afterwords>5中进行的过滤是在内存中完成的。

据我所知,IQueryable从不执行,它只是将Linq查询转换为可查询的格式,以便在请求时执行


在这种情况下,我猜当它被要求转换成一个列表时,它会查询结果。关于第102行和第104行的争论毫无意义,因为它们都代表一行。

是的,这就是我的想法,也是我设计应用程序的方式。然而,当应用程序执行第101行时,我在SQL Profiler中看到一条SQL语句飞过,然后是第101行返回的每个结果的另一条SQL语句。我可以确认发布的是什么反逻辑。查询在线执行101@Antilogic:编译查询的过程可能需要有关数据库结构的信息,但在该阶段不会获取任何数据。如果它这样做了,那么当你以后使用结果时,它将不会得到任何东西。你是对的,但是你在吹毛求疵。收费表在104行,不是102行。这不是一个骗人的问题,他想知道编译查询是否意味着它会立即执行,而不是三行中的哪一行是语句。我想它是在102/104执行的,但当我运行调试器和SQL分析器时,我看到一条SQL语句在101执行之后运行,然后是12条SQL语句(101上的每个结果对应一条)跑102/104@Antilogic:它涉及到如何编写编译后的查询,对吗?如果不能延迟,则它将立即执行。@Alan,请参阅我更新的原始帖子,其中包含编译查询的示例。@Antilogic在调试器中逐个执行语句时,您可以看到这种行为。在没有断点的情况下运行这两个语句,看看发出了多少SQL语句。我认为这个查询实际上是在第101行执行的(甚至在调用ToList之前)。否。第101行创建查询。在获取实际数据时执行查询。如果不是已编译的查询,请检查linq 2 sql提供程序源代码。对于已编译的查询,它位于第101行。问题是“查询何时实际针对数据库执行”,而不是委托何时执行。@Peter。这个委托创建并执行查询。起初我以为它只是创造了一个。我错了-我再检查一下痕迹。如果需要有关数据库结构的信息,可能会有一些流量,但实际的查询不是通过编译来执行的。例如,本页明确指出,可以在编译查询后提供参数值,如果同时执行查询,这是不可能的:调用编译后的查询方法会导致查询在数据库上运行。我用一个简单的数据库检查了多次。当然,您可以传递参数值,我不是说编译导致它执行,我是说调用编译后的查询方法导致它执行,而不是.ToList()方法。