本文转自:http://www.binaryintellect.net/articles/165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx

When you make any additions, modifications and deletions to an Entity  Framework DbSet and call SaveChanges(), EF starts a new transaction and executes  all the INSERT, UPDATE and DELETE operations inside that newly created  transaction. If the call to SaveChanges() succeeds the underlying transaction is  committed, otherwise the transaction is rolled back. In some cases you may want  that multiple calls to SaveChanges() be executed in the same transaction.  Luckily, Entity Framework 6 provides an easy way to accomplish the same.

Let's assume that you have an Entity Framework data model with Customer  entity as shown below:

Now suppose that you wrote the following code to add two Customer records to  the database.

NorthwindEntities db = new NorthwindEntities();

Customer obj1 = new Customer();
obj1.CustomerID = "ABCDE";
obj1.CompanyName = "Company 1";
obj1.ContactName = "Contact 1";
obj1.Country = "USA";
db.Customers.Add(obj1); db.SaveChanges();

Customer obj2 = new Customer();
obj2.CustomerID = "PQRST";
obj2.CompanyName = "Company 2";
obj2.ContactName = "Contact 2";
obj2.Country = "USA";
db.Customers.Add(obj2); db.SaveChanges();

In this case two calls to SaveChanges() are made. The first call adds the  first Customer to the database and the second call adds the other Customer to  the database. If the second call to SaveChanges() fails for some reason the  first Customer still gets added to the database because each call to SaveChanges()  runs in its own transaction.

Now let's modify this code as shown below:

using(NorthwindEntities db = new NorthwindEntities())
{
DbContextTransaction transaction = db.Database.BeginTransaction();

try
{
//insert a record
Customer obj1 = new Customer();
obj1.CustomerID = "ABCDE";
obj1.CompanyName = "Company 1";
obj1.ContactName = "Contact 1";
obj1.Country = "USA";
db.Customers.Add(obj1); //first call to SaveChanges() db.SaveChanges();

//insert another record
Customer obj2 = new Customer();
obj2.CustomerID = "PQRST";
obj2.CompanyName = "Company 2";
obj2.ContactName = "Contact 2";
obj2.Country = "USA";
db.Customers.Add(obj2); //second call to SaveChanges() db.SaveChanges();

transaction.Commit();
}
catch
{
transaction.Rollback();
}
}

Notice that the above code explicitly starts a transaction by calling  BeginTransaction() method on the Database property of the data context. The  BeginTransaction() returns a DbContextTransaction object which is stored in a  local variable. This object is used to either commit or rollback the transaction  later in the code.

The code then adds Customer entities as before and calls SaveChanges() after  each addition. This time since our code is explicitly creating a transaction,  both the calls to SaveChanges() are treated as the part of this transaction. If  both the calls to SaveChanges() are successful we call Commit() method of  DbContextTransaction object. If any of them fails we call the Rollback() method  of DbContextTransaction object.

You can test the above code by setting the CustomerID of the second Customer  to a string longer than five characters.

Note: There is also UseTransaction() method that can be used if you wish to couple EF  operations with plain ADO.NET transactions.

That's it for now! Keep coding !!

Bipin Joshi is a software consultant, trainer, author and a yogi having 21+ years of experience in software development. He conducts online courses in ASP.NET MVC / Core, jQuery, AngularJS, and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also teaches Ajapa Meditation to interested individuals. To know more about him click here.

[转]Wrapping multiple calls to SaveChanges() in a single transaction的更多相关文章

  1. Enlisting multiple 1-phase aware participants in the same transaction

    In some cases it may be necessary to enlist participants that aren't two-phase commit aware into a t ...

  2. 从文件中读取字符-多次调用read characters from file multiple calls

    [抄题]: 接口:int read4(char * buf)一次从文件中读取 4 个字符.返回值是实际读取的字符数. 例如,如果文件中只剩下 3 个字符,则返回 3.通过使用read4 接口,实现从文 ...

  3. Oracle Applications Multiple Organizations Access Control for Custom Code

    档 ID 420787.1 White Paper Oracle Applications Multiple Organizations Access Control for Custom Code ...

  4. Entity Framework中DbContext结合TransactionScope提交事务的正确方式

    问: I would like know what is the best possible way to implement transactions with DBContext. In part ...

  5. postgresql大批量数据导入方法

    一直没有好好关注这个功能,昨天看了一下,数据库插入有瓶颈,今天研究了一下: 主要有以下方案: 1.使用copy从文件导入: copy table_001(a, b, "f", d, ...

  6. XA Transactions Restrictions on XA Transactions

    小结: 1.innodb支持XA事务: 2.XA协议作为资源管理器(数据库)与事务管理器的接口标准: 3.提交或者回滚的点:必须所有的组件被提交或者被回滚: 4.2阶段 PC-1,TM告知所有RM要准 ...

  7. Wrapping calls to the Rational Functional Tester API——调用Rational Functional Tester封装的API

    转自:http://www.ibm.com/developerworks/lotus/library/rft-api/index.html The Rational GUI automation to ...

  8. WCF Concurrency (Single, Multiple, and Reentrant) and Throttling

    http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and Introduc ...

  9. Learning WCF Chapter1 Exposing Multiple Service Endpoints

    So far in this chapter,I have shown you different ways to create services,how to expose a service en ...

随机推荐

  1. IO模型《二》阻塞IO

    阻塞IO(blocking IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: 当用户进程调用了recvfrom这个系统调用,kernel就开始 ...

  2. Django的文件上传以及预览、存储

    思路: 文件上传通过前端的input标签,input设置display:none属性. 内容显示需要让前端通过<img>标签读取图片内容,可以通过<label>标签连接< ...

  3. Cygwin apt-cyg ”MD5 sum did not match”

    直接编辑apt-cyg 文件,找到md5sum,替换修改成sha512sum. # check the md5 digest=`cat "desc" | awk '/^instal ...

  4. I/O(输入/输出)---序列化与反序列化

    概念: 序列化就是将对象的状态存储到特定的介质中的过程,也就是将对象状态转换为可保持或传输格式的过程. 反序列化则是从特定存储介质中将数据重新构建对象的过程.可以将存储在文件上的对象信息读取,然后重新 ...

  5. Effective Java 3rd.Edition 翻译

    推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象 第1项:用静态工厂方法代替构造器 第2项:遇到多个构造器参数时要考虑使用构建器 第3项:用私有构造器或者枚举类型强化Singleton属性 第 ...

  6. SpringCloud-Zuul搭建

    一.创建工程,在pom中引入Zuul 二.重写路由加载类,实在路由的动态注册和路由转发 package com.genius.gateway.zuul; import com.genius.gatew ...

  7. 查看 tensorflow 是GPU版本 还是CPU版本

    在Python环境中输入: import os from tensorflow.python.client import device_lib os.environ["TF_CPP_MIN_ ...

  8. web 服务器安全防范

    apache 关闭目录 配置文件:安装目录/Apache/conf/httpd.conf <Directory /> #默认就会把/ 的目录暴漏出来:关闭方法: Options -Inde ...

  9. [洛谷P4721]分治FFT

    NTT入门,放个板子 // luogu-judger-enable-o2 #include <bits/stdc++.h> using namespace std; #define fr( ...

  10. UESTC - 1137 数位DP

    #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #i ...