zoukankan      html  css  js  c++  java
  • .NET MVC+ EF+通用存储过程实现增删改功能以及使用事物处理

    引摘:

    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, 20),
                      new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, 200)    //输出一定要定义字符类型长度 以免报错
                    };
                if (string.IsNullOrEmpty(strUpdateTime))
                { Param[0].Value = DBNull.Value; }
                else
                { Param[0].Value = strUpdateTime; }
    
     
                Param[1].Direction = ParameterDirection.Output;
                Param[2].Direction = ParameterDirection.Output;
    
               
    
                int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
                string rtcode = Param[1].Value.ToString();
                string rtmessage = Param[2].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, 
                                  '2018888888888888',
                                  GETDATE() ,
                                  1                       
                              );
        END;
        commit transaction
        set  @rt_code= '0000';
         set  @rt_msg= '执行成功!';
         return
         end try 
        begin catch
        set  @rt_code= '9999';
         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, 20),
                      new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, 200)    //输出一定要定义字符类型长度 以免报错
                    };
                if (string.IsNullOrEmpty(strUpdateTime))
                { Param[0].Value = DBNull.Value; }
                else
                { Param[0].Value = strUpdateTime; }
    
    
                Param[1].Direction = ParameterDirection.Output;
                Param[2].Direction = ParameterDirection.Output;
    
    
    
                int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
                string rtcode = Param[1].Value.ToString();
                string rtmessage = Param[2].Value.ToString();
    
                return numdata;
    
            }

     存储方法

     public async static Task<int> ExecuteNonQueryAsync(this DefaultDbContext db, string sql, SqlParameter[] sqlParams)
            {
                int numint=0;
                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, 20),
                      new SqlParameter("@rt_msg", System.Data.SqlDbType.NVarChar, 200)    //输出一定要定义字符类型长度 以免报错
                    };
                if (string.IsNullOrEmpty(strUpdateTime))
                { Param[0].Value = DBNull.Value; }
                else
                { Param[0].Value = strUpdateTime; }
    
    
                Param[1].Direction = ParameterDirection.Output;
                Param[2].Direction = ParameterDirection.Output;
    
    
    
                int numdata = await _DbContext.ExecuteNonQueryAsync("SP_AddDelUpdate", Param);
                string rtcode = Param[1].Value.ToString();
                string rtmessage = Param[2].Value.ToString();
                 var oParam = Param[Param.Length - 1];//返回最后一个输出参数
                 
                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 = 0;
                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 = "201896666666666",
                        CityCode = "OO",
                        OrderStatus =8,
                        PayStatus = 0,
                        UpdateTime = DateTime.Now,
                        CreateTime = DateTime.Now,
                        UserID=2,
    
                    };
                  _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);
            }
  • 相关阅读:
    Linux命令——tac、rev
    Linux命令——pr
    Linux命令——column
    【问题】显示每个用户近期登陆系统次数
    Git分支
    如何使用Systemctl管理系统服务和单元?
    IPTables 和 Netfilter 框架
    Nginx安装及配置
    WMware Workstation——时间和时区问题
    WMware Workstation——网络类型:NAT、bridge、host-only
  • 原文地址:https://www.cnblogs.com/Warmsunshine/p/9087782.html
Copyright © 2011-2022 走看看