[英]Linq to SQL - Update Batch
I have the following inline SQL: 我有以下内联SQL:
internal void UpdateWorkflowProcessingByNullToken(Guid processingToken, int numberToProcess)
{
string sql = string.Format(CultureInfo.InvariantCulture,
"UPDATE TOP ({0}) Master.WorkflowEventProcessing " +
"SET ProcessingToken = '{1}' " +
"WHERE ProcessingToken IS NULL",
numberToProcess, processingToken);
this.Database.ExecuteCommand(sql);
}
Inline SQL was used for performance. 内联SQL用于提高性能。 It was my understanding that L2S would create a SQL statement for every row that I needed to update.
据我所知,L2S会为我需要更新的每一行创建一个SQL语句。 And that was taking too long.
这花了太长时间。 Note, this was a couple of years ago.
请注意,这是几年前的事了。
Now I have a DBA telling me this: 现在我有一个DBA告诉我这个:
As developers, we've been reluctant to use stored procedures. 作为开发人员,我们一直不愿意使用存储过程。 We like having all of our data code in our C# data layer.
我们喜欢在C#数据层中拥有所有数据代码。 Am I stuck here?
我被困在这里吗? Do I need to use a stored procedure?
我需要使用存储过程吗? Or is there a way to do a mass update with L2S?
或者有没有办法用L2S进行大规模更新?
I remember reading about compiling an L2S query. 我记得读过有关编译L2S查询的内容。 I could look into that as well...
我也可以调查一下......
You can use parameterized SQL commands to execute. 您可以使用参数化SQL命令来执行。 This will generate a reusable query execution plan that will be as efficient as a stored procedure after it is initially created and cached.
这将生成可重用的查询执行计划,该计划在最初创建和缓存之后将与存储过程一样高效。 Each execution you simply supply new parameters.
每次执行都只需提供新参数。
More Details 更多细节
Given the following code that updates a demo database and a table named "Foo" 给出以下代码更新演示数据库和名为“Foo”的表
///////////////////////////////////////////////////////////
// just setup for the context for demo purposes, you would
// reference this.Database in place of creating context.
SqlConnection connection = new SqlConnection("Data Source = .; Initial Catalog = MyDb; Integrated Security = SSPI;");
var dataContext = new System.Data.Linq.DataContext(connection);
///////////////////////////////////////////////////////////
string updateQuery = "UPDATE TOP (@p1) dbo.Foo " +
"SET Data = @p2 " +
"WHERE Data IS NULL";
dataContext.Connection.Open();
var command = dataContext.Connection.CreateCommand();
command.CommandText = updateQuery;
command.CommandType = System.Data.CommandType.Text;
var param1 = new SqlParameter("@p1", System.Data.SqlDbType.Int);
param1.Value = 3;
command.Parameters.Add(param1);
var param2 = new SqlParameter("@p2", System.Data.SqlDbType.Int);
param2.Value = 1;
command.Parameters.Add(param2);
command.Prepare();
command.ExecuteNonQuery();
param2.Value = 5;
command.ExecuteNonQuery();
From the profiler output you can see it calls sp_prepexec 从分析器输出中,您可以看到它调用sp_prepexec
declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@p1 int,@p2 int',N'UPDATE TOP (@p1) dbo.Foo SET Data = @p2 WHERE Data IS NULL',@p1=3,@p2=1
select @p1
and executes the statement passing the parameters 3 and 1 then when param2.Value is set to 5 and the command executed again the profiler shows it reusing the prepared command (thus no recompiling or new execution plan generated) 并执行传递参数3和1的语句,然后当param2.Value设置为5并再次执行命令时,分析器显示它重用准备好的命令(因此不会重新编译或生成新的执行计划)
exec sp_execute 1,@p1=3,@p2=5
This is what the profiler output looks like, FYI... 这就是分析器输出的样子,仅供参考...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.