引摘:

1、EF对事务进行了封装:无论何时执行任何涉及Create,Update或Delete的查询,都会默认创建事务。当DbContext类上的SaveChanges()方法被调用时,事务就会提交,saveChange()是有事务性的
2. 依赖多个不同的Context的操作(即分布式操作)或者多次调用context.saveChanges()操作,会脱离EF事务封装,此时可使用TransactionScope实现事务操作

选择合适的事务管理  下面一一对号入座:
1、如果只有一个DbContext类,那么应该尽力使用EF的默认事务管理。我们总应该将所有的操作组成一个在相同的DbContext对象的作用域中执行的工作单元,SaveChanges()方法会处理提交事务。
2、如果使用了多个DbContext对象,那么管理事务的最佳方法可能就是把调用放到TransactionScope对象的作用域中了。
3、如果要执行原生SQL,并想把这些操作和事务关联起来,那么应该使用EF提供的Database.BeginTransaction()方法。然而这种方法只支持EF6,不支持之前的版本。
4、EF 6起,EF在DbContext对象上提供了Database.BeginTransaction()方法,当使用上下文类在事务中执行原生SQL命令时,这个方法特别有用。

1、控制器实现

         /// <summary>
/// 增删改 调用存储过程 返回json格式
/// </summary>
/// <returns></returns>
public async Task<ActionResult> AddORDelORUpdate()
{
string strUpdateTime =DateTime.Now.ToString();
SqlParameter[] Param =
{ //new SqlParameter("@UpdateTime", System.Data.SqlDbType.DateTime),
new SqlParameter("@UpdateTime", System.Data.SqlDbType.VarChar),
new SqlParameter("@rt_code", System.Data.SqlDbType.NVarChar, ),
new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, ) //输出一定要定义字符类型长度 以免报错
};
if (string.IsNullOrEmpty(strUpdateTime))
{ Param[].Value = DBNull.Value; }
else
{ Param[].Value = strUpdateTime; } Param[].Direction = ParameterDirection.Output;
Param[].Direction = ParameterDirection.Output; int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
string rtcode = Param[].Value.ToString();
string rtmessage = Param[].Value.ToString(); return AsResult.Success(); }

2、存储过程

create PROCEDURE [dbo].[SP_AddDelUpdate]
(
@UpdateTime varchar(50),
@rt_code varchar(20) output,
@rt_msg nvarchar(200) output
)
AS
BEGIN
;
begin transaction
begin try
--if(@UpdateTime!=null)
BEGIN
update TRA_BargainOrder_Test set UpdateTime=@UpdateTime ; INSERT INTO TRA_BargainOrder_Test(
UserID,
CityCode,
UpdateTime,
BargainOrderCode,
CreateTime,
OrderStatus )
VALUES ( 3,
'SZ',
@UpdateTime,
'',
GETDATE() ,
1
);
END;
commit transaction
set @rt_code= '';
set @rt_msg= '执行成功!';
return
end try
begin catch
set @rt_code= '';
set @rt_msg= '失败,请稍候再试!';
rollback transaction
end catch
END
        /// <summary>
/// 返回int类型 增删改 调用存储过程
/// </summary>
/// <returns></returns>
public async Task<int> Add_ORDelORUpdate()
{
string strUpdateTime = DateTime.Now.ToString();
SqlParameter[] Param =
{ //new SqlParameter("@UpdateTime", System.Data.SqlDbType.DateTime),
new SqlParameter("@UpdateTime", System.Data.SqlDbType.VarChar),
new SqlParameter("@rt_code", System.Data.SqlDbType.NVarChar, ),
new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, ) //输出一定要定义字符类型长度 以免报错
};
if (string.IsNullOrEmpty(strUpdateTime))
{ Param[].Value = DBNull.Value; }
else
{ Param[].Value = strUpdateTime; } Param[].Direction = ParameterDirection.Output;
Param[].Direction = ParameterDirection.Output; int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
string rtcode = Param[].Value.ToString();
string rtmessage = Param[].Value.ToString(); return numdata; }

存储方法

 public async static Task<int> ExecuteNonQueryAsync(this DefaultDbContext db, string sql, SqlParameter[] sqlParams)
{
int numint=;
using (var cmd = db.Database.Connection.CreateCommand())
{
try
{
await db.Database.Connection.OpenAsync();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(sqlParams); numint = await cmd.ExecuteNonQueryAsync();
cmd.Connection.Close(); }
catch (Exception ex)
{
_Logger.Error("执行数据" + ex.Message);
//throw new Exception("提交失败." + ex.Message);
}
finally
{
cmd.Connection.Dispose();
}
return numint; }
}
       /// <summary>
/// 返回类型 增删改 调用存储过程 返回一个输出参数值
/// </summary>
/// <returns></returns>
public async Task<object> Add_ORDel_OR_Update()
{
string strUpdateTime = DateTime.Now.ToString();
SqlParameter[] Param =
{ //new SqlParameter("@UpdateTime", System.Data.SqlDbType.DateTime),
new SqlParameter("@UpdateTime", System.Data.SqlDbType.VarChar),
new SqlParameter("@rt_code", System.Data.SqlDbType.NVarChar, ),
new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, ) //输出一定要定义字符类型长度 以免报错
};
if (string.IsNullOrEmpty(strUpdateTime))
{ Param[].Value = DBNull.Value; }
else
{ Param[].Value = strUpdateTime; } Param[].Direction = ParameterDirection.Output;
Param[].Direction = ParameterDirection.Output; int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
string rtcode = Param[].Value.ToString();
string rtmessage = Param[].Value.ToString();
var oParam = Param[Param.Length - ];//返回最后一个输出参数 return oParam;   }

增删改操作使用事物处理 这个主要结合ado.net方式

        /// <summary>
/// 异步执行带有参数的存储过程公共方法 增删改操作以及返回带有输出的参数 结合ADO.NET的事物处理
/// 这种情况,我们不能使用Database.BeginTransaction方法,因为我们需要将SqlConnection和SqlTransaction对象传给该函数,并把该函数放到我们的事务里。需要首先创建一个SqlConnection,然后开始SqlTransaction
/// </summary>
/// <param name="db"></param>
/// <param name="sql"></param>
/// <param name="sqlParams"></param>
/// <returns></returns>
public async static Task<int> ExecuteNonQueryAsync(this DefaultDbContext db, string sql, SqlParameter[] sqlParams)
{
var connectionString = ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString; int numint = ;
using (var conn = new SqlConnection(connectionString))
{
await conn.OpenAsync();
using (var dbContextTransaction = conn.BeginTransaction(System.Data.IsolationLevel.Snapshot))
{ try
{ var cmd = new SqlCommand();
using ( cmd.Connection = conn)
{ cmd.Transaction = dbContextTransaction;
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(sqlParams); numint = await cmd.ExecuteNonQueryAsync();
//cmd.Connection.Close();
dbContextTransaction.Commit();
} // db.Database.UseTransaction(dbContextTransaction);
//using (var dbcontext =
// new DefaultDbContext(conn, contextOwnsConnection: false))
//{
// dbcontext.Database.UseTransaction(dbContextTransaction); // //dbcontext.SaveChanges();
//}
//dbContextTransaction.Commit(); }
catch (Exception ex)
{
dbContextTransaction.Rollback();
_Logger.Error("执行数据" + ex.Message); }
finally
{
dbContextTransaction.Dispose();
}
return numint;
}
}
}

单个savechanges上下文实现事务 Database.BeginTransaction

 public ActionResult Index()
{
var dbContextTransaction = _DbContext.Database.BeginTransaction();
try
{
TRA_BargainOrder_Test TRA = new TRA_BargainOrder_Test
{
BargainOrderCode = "",
CityCode = "OO",
OrderStatus =,
PayStatus = ,
UpdateTime = DateTime.Now,
CreateTime = DateTime.Now,
UserID=, };
_DbContext.TRA_BargainOrders.Add(TRA);
} _DbContext.SaveChanges();
dbContextTransaction.Commit();
}
catch(Exception ex)
{
dbContextTransaction.Rollback();
_Logger.Error("执行数据" + ex.Message);
}
finally
{
dbContextTransaction.Dispose();
}
var data = _DbContext.TRA_BargainOrders.ToList(); return View(data);
}

.NET MVC+ EF+通用存储过程实现增删改功能以及使用事物处理的更多相关文章

  1. ASP.NET MVC + EF 利用存储过程读取大数据,1亿数据测试很OK

    看到本文的标题,相信你会忍不住进来看看! 没错,本文要讲的就是这个重量级的东西,这个不仅仅支持单表查询,更能支持连接查询, 加入一个表10W数据,另一个表也是10万数据,当你用linq建立一个连接查询 ...

  2. Ibatis调用存储过程实现增删改以及分页查询

    1.Ibatis实现增删改操作很简单了,通常我是将某一模块的增删改功能写在一个存储过程里,通过一个标识符去区分执行增加还是修改抑或删除操作. statement: <!-- 存储过程:实现学生的 ...

  3. MVC创建XML,并实现增删改

    原文:MVC创建XML,并实现增删改 如果创建如下的XML: <?xml version="1.0" encoding="utf-8" standalon ...

  4. ASP.NET MVC + EF 利用存储过程读取大数据

    ASP.NET MVC + EF 利用存储过程读取大数据,1亿数据测试很OK 看到本文的标题,相信你会忍不住进来看看! 没错,本文要讲的就是这个重量级的东西,这个不仅仅支持单表查询,更能支持连接查询, ...

  5. oracle-扫盲贴:存储过程实现增删改查

    原文引入:http://blog.csdn.net/yangzhawen/article/details/8617179 oracle-扫盲贴:存储过程实现增删改查 分类: oracle2013-02 ...

  6. .NET MVC+ EF+调用存储过程 多表联查以及VIEW列表显示

    直接上干活,至于网上的一大堆处理方式不予评论,做好自己的就是最好的,供大家不走弯路 1.view页面 <link href="~/Content/bootstrap.css" ...

  7. Asp.net MVC4 使用EF实现数据库的增删改查

    EF的使用 步骤: (1)将EF添加到项目:在Model右击添加新建项 找到ADO.NET实体数据模型,接着... (2)实现数据库的增删改查       查询 (因为在Model中已经添加EF实体了 ...

  8. 使用EF实现数据库的增删改查

    EF的使用步骤:(1)将EF添加到项目:在Model右击添加新建项找到ADO.NET实体数据模型,接着…(2)实现数据库的增删改查查询(因为在Model中已经添加EF实体了,所以就可以在Control ...

  9. MVVM架构~knockoutjs与MVC配合,实现列表的增删改功能

    返回目录 MVC与MVVM的模型 在MVC实例项目中,为我们提供了简单的增删改查功能,而这种功能的实现与具体的Model很有关系,或者说它与后台数据库的关系过于紧密了,而对于开发人员来说当页面布局修改 ...

随机推荐

  1. 主成分分析PCA

    PCA(Principal Component Analysis)不仅仅是对高维数据进行降维,更重要的是经过降维去除了噪声,发现了数据中的模式. PCA把原先的n个特征用数目更少的m个特征取代,新特征 ...

  2. UAC 实现原理及绕过方法

    目录 0x00 UAC 工作流程 0x01 UAC 实现方法(用户登陆过程) 0x02 UAC 架构 0x03 触发UAC 0x04 UAC 虚拟化 0x05 UAC 逆向分析 1x00 UAC By ...

  3. 共享内存:mmap函数实现

    内存映射的应用: 以页面为单位,将一个普通文件映射到内存中,通常在须要对文件进行频繁读写时使用,这样用内存读写代替I/O读写,以获得较高的性能; 将特殊文件进行匿名内存映射,能够为关联进程提供共享内存 ...

  4. android使用GestureDetector实现手势下滑关闭页面的效果。

    实现类似Android风云直播手机端注册登录页,当手势向下滑动的时候,关闭页面的效果. 使用GestureDetector来实现这个效果,当手势在屏幕上面滑动的时候 ,会掉用onFling方法,所以, ...

  5. Python实现:十进制数与(2~16进制数)之间的互相转换

    (最开始源于牛客网上的一道编程题 : [编程题] 数制转换) 将X进制转为int十进制的功能函数:(乘X次方各位数的加和法) # 将X进制转为int十进制的功能函数:(乘X次方各位数的加和法) def ...

  6. android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器

    一.基础知识点学习  1.Android体系结构 如图所示,android 架构分为三层: (1)最底层是linux内核,主要是各种硬件的驱动,如相机驱动(Camera Driver),闪存驱动(Fl ...

  7. 运维自动化之Cobbler系统安装使用详解[good]

    一.简介 Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便(才15k行python代码),使用简单的命令即可完成P ...

  8. 树莓派进阶之路 (007) - 树莓派安装cmake3.5 脚本(原创)

    cmake3.5安装脚本: #!/bin/bash cd echo "安装make" sudo apt-get install make echo "安装cmake&qu ...

  9. EF的表左连接方法Include和Join

    在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...

  10. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...