LINQtoSQL*Compiled*QueriesandWhentoExecute我有以下编译查询。privatestaticFuncfunc=CompiledQuery.Compile((Dbdb,intid)=>fromiindb.Itemswherei.ID==idselecti);当我这样做时,它立即在数据库上执行vardb=newDb()varquery=func(db,5);//查询在这里和以前一样命中数据库varresult=query.SingleOrDefault();//发生在内存中,但如果不编译此查询,如varquery=fromiindb.Itemswherei.ID==idselecti然后它在完成后在数据库上执行varresult=query.SingleOrDefault();这是预期的行为吗?注意:这是WhenreturnsacompiledqueryexecutedbyIQueryable?的副本?,但那里的所有答案似乎都不同意我的发现。我已经在那里发布了我的答案,但我不知道如何让人们关注它,因为它已经超过2年了。有趣的问题。将它带到反编译的源代码中,当查询被编译时,会发生以下情况:");如果(CompiledQuery.UseExpressionCompile((LambdaExpression)query))returnquery.Compile();否则返回newFunc(newCompiledQuery((LambdaExpression)query).Invoke);}UseExpressionCompile方法定义如下:privatestaticboolUseExpressionCompile(LambdaExpressionquery){returntypeof(ITable).IsAssignableFrom(query.Body.Type);}对于您定义的表达式,计算结果为false,因此请使用else大小写。调用是这样的:privateTResultInvoke(TArg0arg0,TArg1arg1)whereTArg0:DataContext{return(TResult)this.ExecuteQuery((DataContext)arg0,newobject[2]{(object)arg0,(object)arg1});}ExecuteQuery就像:privateobjectExecuteQuery(DataContextcontext,object[]args){if(context==null)throwSystem.Data.Linq.Error.ArgumentNull("context");if(this.compiled==null){lock(this){if(this.compiled==null)this.compiled=context.Provider.Compile((Expression)this.query);}}返回this.compiled.Execute(context.Provider,args)。返回值;在这种情况下,我们的提供者是SqlProvider类,而SqlProvider.CompiledQuery是实现ICompiledQuery的类。执行该类的执行:publicIExecuteResultExecute(IProviderprovider,object[]arguments){if(provider==null)throwSystem.Data.Linq.SqlClient.Error.ArgumentNull("provider");SqlProvidersqlProvider=providerasSqlProvider;如果(sqlProvider==null)throwSystem.Data.Linq.SqlClient.Error.ArgumentTypeMismatch((object)"provider");如果(!SqlProvider.CompiledQuery.AreEquivalentShapes(this.originalShape,sqlProvider.services.Context.LoadOptions))throwSystem.Data.Linq.SqlClient.Error.CompiledQueryAgainstMultipleShapesNotSupported();否则返回sqlProvider.ExecuteAll(this.query,this.queryInfos,this.factory,arguments,this.subQueries);}SqlProvider.ExecuteAll调用SqlProvider.Execute,这是一个非常大的方法,所以我将发布亮点:privateIExecuteResultExecute(Expressionquery,SqlProvider.QueryInfoqueryInfo,IObjectReaderFactoryfactory,object[]parentArgs,object[]userArgs,ICompiled]subQueries,objectlastResult){this.InitializeProviderMode();数据库连接数据库Connection=this.conManager.UseConnection((IConnectionUser)这个);尝试{DbCommand命令=dbConnection.CreateCommand();command.CommandText=queryInfo.CommandText;command.Transaction=this.conManager.Transaction;command.CommandTimeout=this.commandTimeout;this.AssignParameters(command,queryInfo.Parameters,userArgs,lastResult);this.LogCommand(this.log,命令);++this.queryCount;switch(queryInfo.ResultShape){caseSqlProvider.ResultShape.Singleton:DbDataReaderreader1=command.ExecuteReader();...案例SqlProvider.ResultShape.Sequence:DbDataReaderreader2=command.ExecuteReader();...默认值:返回(IExecuteResult)newSqlProvider.ExecuteResult(命令,queryInfo.Parameters,(IObjectReaderSession)null,(对象)command.ExecuteNonQuery(),true);}}最后{this.conManager.ReleaseConnection((IConnectionUser)this);在获取和释放连接之间,它是sql命令的补充,所以我说你是对的。与流行的看法相反,在延迟执行方面,编译查询的行为与未编译查询不同。我很确定您可以从MS下载实际的源代码,但我没有那个方便,Resharper6有一个很好的反编译功能,所以我只是使用它。除了以下内容外,我对安德鲁巴雷特的回答没有任何补充:是的,这是正确的。在您询问之前,它不会获取任何东西。有关延迟加载与立即加载的信息,请参见MSDN。特别是,您可以打开/关闭延迟加载。请参阅有关此问题的最流行答案,其中创建了最终列表。里面有个select语句,把它发出去,要结果。LINQ将尽可能长时间地向数据库发送请求。顺便说一句,如果您设置DataContext.Log属性,您可以轻松调查:db.Log=Console.Out;然后您可以在控制台上查看SQL语句。通过单步执行程序,您可以准确地看到SQL语句何时命中数据库。以上就是C#学习教程的全部内容:LINQtoSQL*编译*查询及何时执行的分享。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表侵权,请点击右边联系管理员删除。如需转载请注明出处: