引摘:

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. SpannableStringUtil实现丰富文字效果

    代码地址如下:http://www.demodashi.com/demo/15007.html 前言 在android开发中,我们不免会用到 TextView 的各种显示效果,如字体样式,颜色,大小, ...

  2. ubuntu 终端中文显示乱码问题!

    1 Alt+Ctrl+F1 进入第一个终端,发现中文乱码. 2 安装zhcon. sudo apt-get install zhcon 3 输入下面命令,启动zhcon,中文显示正常. zhcon - ...

  3. Xshell连接Ubuntu失败问题

    转自:https://www.linuxidc.com/Linux/2017-08/146222.htm Xshell是一个安全终端模拟软件,可以进行远程登录.我使用XShell的主要目的是在Wind ...

  4. tensorflow没有代码提示的问题

    在tensorflow包下的__init__.py文件中定义了一个contrib变量表示tensorflow.contrib包下的内容,但是tensorflow.contrib这个包是懒加载的,也就是 ...

  5. Eclipse中10个最有用的快捷键组合(转)

    Eclipse中10个最有用的快捷键组合   一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升.   ...

  6. 如何创建magento模块z之Hello World例子(转)

    步骤:1.创建一个Hello World模块2.为这个模块配置路由3.为这个模块创建执行控制器 创建Hello World模块 创建模块的结构目录:app/core/local/Sjolzy/Hell ...

  7. 【Spring】SpringMVC之详解AOP

    1,AOP简介 Aspect Oriented Programming  面向切面编程.AOP还是以OOP为基础,只不过将共同逻辑封装为组件,然后通过配置的方式将组件动态切入到原有组件中.这样做的有点 ...

  8. 【C语言】练习5-8

     题目来源:<The C programming language>中的习题P92  练习5-8: 一个日期转换的问题,把某月某日这种日期表示形式转换为某年中第几天的表示形式,反之亦然.例 ...

  9. rhel7 ifconfig command not found

    同事扔过来一个rhel7.2的系统,登录后发现没有安装ifconfig命令: # ifconfig -bash: ifconfig: command not found 先看看环境变量: # echo ...

  10. Python -- map, Lambda, filter and reduce

    map(func, seq)对seq中的每一个元素,调用func并返回结果.典型的应用是使用lambda函数. >>> def square(x): return x**2 > ...