2011-01-28 115 views
3

我有一个包含10个属性的客户实体。C#/ SQL:在一个事务中执行多个插入/更新

  • 其中7个属性保存在客户表中。
  • 其中3个属性保存在测试表中。

测试表中的3个属性是CustomerId,Label,Text。

当我询问这3个属性,我得到3集是这样的:

CustomerId | Label | Text 
1005  | blubb | What a day 
1006  | hello | Sun is shining 
0007  |  | 

当我救他们,我必须在测试表

打电话给我的存储过程3次在我的SP我检查其数据集与特定的customerId AND标签已经存在 然后我做一个UPDATE或INSERT。

你将如何与所有CommandText,CommandType,ExecuteNonQuery等东西调用存储过程3次?

+0

是有代表客户的对象,还是要插入测试表的实体? – msarchet 2011-01-28 15:11:41

回答

8

最简单的方法是:使用TransactionScope类。

简而言之呼叫成块,如:

using(TransactionScope ts = new TransactionScope()){ 

    using(SqlConnection conn = new SqlConnection(myconnstring) 
    { 
     conn.Open(); 
... do the call to sproc 

     ts.Complete(); 
     conn.Close(); 
    } 
} 

[编辑]我还添加了SqlConnection的,因为我是这个模式非常有范。 using关键字确保连接关闭,如果发生错误,transcation回滚

1

好了,的SqlTransaction跨越了三个的ExecuteNonQuery是最简单的,但一些备选方案:

  • 使用XML数据类型传递作为XML所有三个;将sproc中的XML(SQL服务器具有此功能)解析为3条记录
  • 使用“表值参数”在单个调用中传递它们 - 注意,这需要在DB处额外定义以表示结构化数据
  • 如果数据量庞大(3000而不是3),使用SqlBulkCopy到一个临时表中,然后运行一个存储过程将数据移动到真实表中的一个基于集的操作

最后,提防“内部平台效应” - 听起来有点像数据库中的数据库。

+0

你有我的一个小片段的跨越3 ExecuteNonQuery的sqltransaction,请吗? – Elisabeth 2011-01-28 15:29:24

+0

@Lisa我相信MSDN有... http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspx – 2011-01-28 15:37:07

0

您应该将INSERT封装到事务中。不好的方法是在ADO.NET中使用TransactionScope,好的方法是编写一个存储过程,并在您的proc中写入BEGIN和COMMIT/ROLLBACK您的事务。您不希望在维护事务时来回切换客户端到服务器,因为您将损害concurreny和性能(在事务结束前插入的资源将被锁定)。

BEGIN TRAN 开始尝试这 INSERT INSERT COMMIT TRAN END TRY BEGIN CATCH PRINT ERROR_MESSAGE() - 你可以用扔在SQL Server 2012中,以retrhrow错误 ROLLBACK END CATCH

相关问题