zoukankan      html  css  js  c++  java
  • .net Dapper 学习系列(2) ---Dapper进阶

    前言


    在上一小节中,我们学习、实践和总结记录了Dapper的基础用法。而这一小节,我们继续深入的学习一下Dapper这个小型

    ORM框架的其他用法。在这个实列中,我们会用到两个有关联的表。

    前期准备


    首先,还是沿用之前的的项目。库还是原来的DemoDb数据库。如还是不清楚的,可以看上一篇。

    在DemoDb数据库新增产品表

    //用户表
    create table[sys_user](
    	[user_id] [nvarchar](36) primary key  not null,
    	[u_id] [nvarchar](20) null,
    	[u_password] [nchar](50) null,
    	[gender] [nchar](1) null,
    	[user_name] [nvarchar](50) null,
    	[creation_time] [datetime] default(getdate()) null,
    	[status] [nvarchar](1) null,
    )
    
    //产品表
    create table [sys_product](
    	[productid] [nvarchar](36) primary key  not  null,
    	[productname] [nvarchar](50) null,
    	[productDesc] [nvarchar](50) null,
    	[CreateTime] [datetime] defatul(getdate()) null,
    	[user_id] [nvarchar](36) null,
    )
    
    

    在Model 中添加 产品表的类

    //用户
    public class sys_user_sqlserver
    {
            [DisplayName("用户主键")]
            public string user_id { get; set; }
            [DisplayName("登录名称")]
            public string u_id { get; set; }
            [DisplayName("登录密码")]
            public string u_password { get; set; }
            [DisplayName("性别")]
            public string gender { get; set; }
            [DisplayName("姓名")]
            public string user_name { get; set; }
            [DisplayName("创建时间")]
            public string creation_time { get; set; }
            [DisplayName("状态")]
            public string status { get; set; }
     }
    
    //产品
    public class sys_product_sqlserver
    {
            [DisplayName("产品主键")]
            public string productid { get; set; }
            [DisplayName("产品名称")]
            public string productname { get; set; }
            [DisplayName("产品描述")]
            public string productDesc { get; set; }
            [DisplayName("用户主键")]
            public string user_id { get; set; }
            //public sys_user_sqlserver userown { get; set; }
            [DisplayName("创建时间")]
            public DateTime CreateTime { get; set; }
    }
    

    单表批量添加


    using System.Configuration;//ConfigurationManager
    using Dapper;//SqlMapper
    using System.Data;//IDbConnection
    using System.Data.SqlClient; //SqlConnection
    using Newtonsoft.Json;//
    
    using MySql.Data.MySqlClient;
    using Newtonsoft.Json.Linq;
    using System.Diagnostics;//mysql
    
    /*连接字符串*/
    private static string connstr_sqlserver = ConfigurationManager.ConnectionStrings["lc"].ToString();
    
    /// <summary>
    /// 单表批量添加
    /// </summary>
    /// <param name="user">泛型集合</param>
    /// <returns>成功返回1,失败返回0</returns>
    [HttpPost]
    public int Add_Many(List<sys_user_sqlserver> user)
    {
         /*模拟数据*/
        user = new List<sys_user_sqlserver> { 
           new sys_user_sqlserver { user_id =Guid.NewGuid().ToString(), u_id = "Admin", u_password = "admin001", gender = "m", user_name = "管理员", status = "y" },
           new sys_user_sqlserver { user_id =Guid.NewGuid().ToString(), u_id = "User", u_password = "user001", gender = "m", user_name = "用户", status = "y" },
           new sys_user_sqlserver { user_id =Guid.NewGuid().ToString(), u_id = "ZhangSan", u_password = "zhangsan001", gender = "m", user_name = "张三", status = "y" },
           new sys_user_sqlserver { user_id =Guid.NewGuid().ToString(), u_id = "LiSi", u_password = "LiSi001", gender = "w", user_name = "李思", status = "y" },
           new sys_user_sqlserver { user_id =Guid.NewGuid().ToString(), u_id = "ZhaoQian", u_password = "zhaoqiao001", gender = "w", user_name = "赵钱", status = "y" },
         };
         /*声明结果*/
         int result = 0;
         /*连接Sqlserver 数据库*/
         using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
         {
             /*sql 语句*/
             string sql_add = @"insert into sys_user(user_id,u_id,u_password,gender,user_name,status)";
             sql_add += " values (newid(),@u_id,@u_password,@gender,@user_name,@status)";
             /*执行Execute(参数1,参数2) 参数1:sql语句,参数2:(可以是一个对象也可以是一个泛型集合)*/
             int results = conn.Execute(sql_add, user);
             if (results > 0) { result = 1; }
          }
          /*成功返回1,失败返回0*/
          return result;
    }
    
    

    多表查询


    /// <summary>
    /// 多表查询
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public JsonResult ManyToOne()
    {
         using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
          {
              string sql = "select p.productid,p.productname,p.productDesc,u.user_name  from sys_product p ";
              sql += "join sys_user u on p.user_id=u.user_id";
              #region 方式1 返回泛型
               var product = conn.Query<sys_product_sqlserver, sys_user_sqlserver, sys_product_sqlserver>(sql,
                     (products, users) =>
                      {
                           products.userown = users; return products;
                       }, splitOn: "user_name");
              #endregion
              #region 方式2  默认返回 dynamic
              ////var product = conn.Query(sql);
              #endregion
              return Json(product, JsonRequestBehavior.AllowGet);
          }
    }
    
    

    调用存储过程


    /*创建存储过程*/
    create proc proc_queryUser 
    @user_id varchar(50)
    as
    begin
    	select * from sys_user where user_id=@user_id;
    end
    
    /*在程序中使用Dapper调用存储过程*/
    
    /// <summary>
    /// Dapper 调用存储过程
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public JsonResult Get_Proc(string id)
    {
          /*模型接收数据*/
          stirng Id="7384A533-44FA-4358-8171-0162F4950292";
          /*打开数据库连接*/
          using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
          {
              #region 方法1
              //var result = conn.Query<sys_user_sqlserver>("proc_queryUser", 
              //new { user_id = id }, null, true, null,
              //CommandType.StoredProcedure); 
              #endregion
              #region 方法2
              /*调用存储过程*/
              var result = conn.Query<sys_user_sqlserver>("proc_queryUser",
              new { user_id = id },
              commandType: CommandType.StoredProcedure);
              #endregion
              /*返回结果集*/
              return Json(result, JsonRequestBehavior.AllowGet);
          }
    }
    
    

    使用QueryMultiple多表查询


    错误写法:
    public SqlMapper.GridReader Get_Readers_Data()
    {
           using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
           {
                 string sql = @"select * from sys_user;select * from sys_product;";
                 #region 方式1 QueryMultiple(sql语句);
                 var data = conn.QueryMultiple(sql);
                 #endregion
                 #region 方式2 QueryMultiple(连接字符串,sql语句);
                 //var data = SqlMapper.QueryMultiple(conn, sql); 
                 #endregion
                 return data;
            } 
    }
    
    public JsonResult Get_All_Data()
    {
       var all = Get_Reader_Data();
       var users = all.Read<sys_user_sqlserver>().ToList();
       var products = all.Read<sys_product_sqlserver>().ToList();
       Dictionary<string, object> dic = new Dictionary<string, object>();
       dic.Add("user",users);
       dic.Add("product",products);
       return Json(dic, JsonRequestBehavior.AllowGet);
    }
    
    
    

    这时我们运行程序,会发现出现如图的错误。错误:阅读器关闭时尝试调用 FieldCount无效[解决方案]。

    分析错误原因:
    *.首先:使用using{}作用域之后,连接会自动关闭。
    *.其次:使用的是DataSet 读取数据库是它会把读到的数据数据存放在本地内存中。但是,Reader则不会。
    *.最后:它只是指向了数据,连接关闭后用reader读取数据当然无法实现。

    所以,正确的做法是,去除Using{}作用域。

    //正确做法
    public SqlMapper.GridReader Get_Readers_Data()
    {
            /*打开数据库连接*/
            IDbConnection conn = new SqlConnection(connstr_sqlserver);
            /*sql语句*/
            string sql = @"select * from sys_product; select * from sys_user";
            #region 方式1 QueryMultiple(sql语句);
            /*调用 QueryMultiple 返回过个结果集 */
            var data = conn.QueryMultiple(sql);
            #endregion
            #region 方式2 QueryMultiple(连接字符串,sql语句);
            //var data = SqlMapper.QueryMultiple(conn, sql); 
            #endregion
            return data;
    }
    
    public JsonResult Get_All_Data()
    {
       var all = Get_Reader_Data();
       var users = all.Read<sys_user_sqlserver>().ToList();
       var products = all.Read<sys_product_sqlserver>().ToList();
       Dictionary<string, object> dic = new Dictionary<string, object>();
       dic.Add("user",users);
       dic.Add("product",products);
       return Json(dic, JsonRequestBehavior.AllowGet);
    }
    
    
    

    注意: 这里查询表顺序和读取表的顺序必须要一样。如果两者顺序不一样是没有数据返回的。 会出现返回值都是NULL的情况。而造成这样的原因是Reader 是按照查询的结果依次读取显示的。 所以,查询表顺序和读取表的顺序必须一样。否则就会出现类似于下图的情况。

    如图所示:


    事务进行多表添加


    [HttpPost]
    public int Get_Tran_Add(List<sys_product_sqlserver> product, sys_user_sqlserver user)
    {
            int result;
            /*连接sqlserver 数据库*/
            using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
            {
                 
                    /*模拟数据*/
                    var ID = Guid.NewGuid();
                    user = new sys_user_sqlserver { user_id = ID.ToString(), u_id = "admin", u_password = "admin", gender = "m", user_name = "管理员", status = "y" };
                    product = new List<sys_product_sqlserver> { 
                    new sys_product_sqlserver{productid=Guid.NewGuid().ToString(),productname="产品1",productDesc="产品描述1",user_id=ID.ToString()},
                    new sys_product_sqlserver{productid=Guid.NewGuid().ToString(),productname="产品2",productDesc="产品描述2",user_id=ID.ToString()},
                    new sys_product_sqlserver{productid=Guid.NewGuid().ToString(),productname="产品3",productDesc="产品描述3",user_id=ID.ToString()},
                    new sys_product_sqlserver{productid=Guid.NewGuid().ToString(),productname="产品4",productDesc="产品描述4",user_id=ID.ToString()},
                    new sys_product_sqlserver{productid=Guid.NewGuid().ToString(),productname="产品5",productDesc="产品描述5",user_id=ID.ToString()}
                    };
                    /*sql语句*/
                    string sql1 = @"insert into sys_user(user_id,u_id,u_password,gender,user_name,status)";
                    sql1 += " values (@user_id,@u_id,@u_password,@gender,@user_name,@status)";
    
                    string sql2 = @"insert into sys_product(productname,productDesc,user_id)";
                    sql2 += " values (@productname,@productDesc,@user_id)";
                     /*注意:要记得打开连接。否则会报错:无效操作。连接被关闭。*/
                    conn.Open();
                    /*开始事务*/
                    IDbTransaction tran = conn.BeginTransaction();
                    try
                    {
                        /*执行事务*/
                        var resultOne = conn.Execute(sql1, user, tran);
                        var resultTwo = conn.Execute(sql2, product, tran);
                        /*提交事务*/
                        tran.Commit();
                        result = 1;
                    }
                    catch (Exception)
                    {
                        /*回滚事务*/
                        tran.Rollback();
                        result = 0;
                        throw;
                      }
             }
             /*成功返回1,失败返回0*/
             return result;
    }
    
    

    注意: 在使用事务的时候注意要加上dbConnection.Open(),因为在BeginTransaction时要求连接是打开的。 而在不使用事务的时候,简单的增删改查可以不用这一句,因为Execute方法中有Open。 否则会报错:无效操作。连接被关闭。


    使用事务进行多表编辑


    [HttpPost]
    public int Get_Tran_Edit(List<sys_product_sqlserver> product, sys_user_sqlserver user)
    {
              int result;
              /*连接sqlserver 数据库*/
              using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
              {
                    //注意要加上dbConnection.Open(),因为在BeginTransaction时要求连接是打开的。而
                    //在不使用事务的时候,简单的增删改查可以不用这一句,因为Execute方法中有Open。否则会报错:无效操作。连接被关闭。
                    /*模拟接收数据*/
                    var ID = "EF2D72DD-5D45-482A-A26E-FF3AF3A39DE9";
                    user = new sys_user_sqlserver { user_id = ID, u_id = "admin1", u_password = "admin1", gender = "w", user_name = "管理员1", status = "n" };
                    product = new List<sys_product_sqlserver> { 
                    new sys_product_sqlserver{productid="04245342-1855-4171-B408-2A04FCF5696B",productname="产品11",productDesc="产品描述11",user_id=ID},
                    new sys_product_sqlserver{productid="C268A332-38B5-49E9-AFC1-E6E9EB62D2A2",productname="产品21",productDesc="产品描述21",user_id=ID},
                    new sys_product_sqlserver{productid="823E4F43-31FC-4355-BA12-925AC7704340",productname="产品31",productDesc="产品描述31",user_id=ID},
                    new sys_product_sqlserver{productid="93E8829E-5ED1-45BF-B979-E22405D092D1",productname="产品41",productDesc="产品描述41",user_id=ID},
                    new sys_product_sqlserver{productid="6EF52CA5-AB9B-41E1-B335-16C86F2A445C",productname="产品51",productDesc="产品描述51",user_id=ID}
                    };
                    /*sql语句*/
                    string sql_add = @"update  sys_user set u_id=@u_id,u_password=@u_password,gender=@gender,";
                    sql_add += "user_name=@user_name,status=@status where user_id=@user_id";
    
                    string sql = @"update sys_product set productname=@productname,productDesc=@productDesc,user_id=@user_id";
                    sql += " where  productid=@productid";
                    /*注意:要记得打开连接。否则会报错:无效操作。连接被关闭。*/
                    conn.Open();
                    /*开始事务*/
                    IDbTransaction tran = conn.BeginTransaction();
                    try
                    {
                        /*执行事务*/
                        var resultOne = conn.Execute(sql_add, user, tran);
                        var resultTwo = conn.Execute(sql, product, tran);
                        /*提交事务*/
                        tran.Commit();
                        result = 1;
                    }
                    catch (Exception)
                    {
                        /*事务回滚*/
                        tran.Rollback();
                        result = 0;
                        throw;
                     }
             }
             /*6.成功返回结果1,失败返回结果0*/
             return result;
    }
    
    

    使用事务进行多表删除


    [HttpPost]
    public int Get_Tran_Del()
    {
              int result;
              /*连接sqlserver 数据库*/
              using (IDbConnection conn = new SqlConnection(connstr_sqlserver))
              {
                    //注意要加上dbConnection.Open(),因为在BeginTransaction时要求连接是打开的。而
                    //在不使用事务的时候,简单的增删改查可以不用这一句,因为Execute方法中有Open。否则会报错:无效操作。连接被关闭。
                    /*注意:要记得打开连接。否则会报错:无效操作。连接被关闭。*/
                    conn.Open();
                    /*开始事务*/
                    IDbTransaction transaction = conn.BeginTransaction();
                    try
                    {
                        /*执行事务*/
                        string query1 = "delete from sys_user where user_id = @user_id";
                        string query2 = "delete from sys_product where user_id = @user_id";
                        conn.Execute(query1, new { user_id = "f2ffed38-9f43-4088-80af-138990a76e60" }, transaction, null, null);
                        conn.Execute(query2, new { user_id = "f2ffed38-9f43-4088-80af-138990a76e60" }, transaction, null, null);
                        /*提交事务*/
                        transaction.Commit();
                        result = 1;
                    }
                    catch (Exception ex)
                    {
                        /*回滚事务*/
                        //出现异常,事务Rollback
                        transaction.Rollback();
                        result = 0;
                        throw new Exception(ex.Message);
                    }
              }
              return result;
    }
    
    

    总结


    好记性不如‘烂笔头’。到目前为止,总结了Dapper 常用的一些操作。如果项目小,又对性能有较高要求的话,可以选择Dapper 这个小型的ORM框架进行项目的快速开发。

  • 相关阅读:
    uva11235 FrequentValues (ST表)
    hdu5449 Robot Dog (树形dp+倍增lca)
    [BZOJ1637][Usaco2007 Mar]Balanced Lineup
    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理
    Luogu1119灾后重建
    [APIO2012]派遣
    [HNOI2004]宠物收养场
    [USACO14DEC] 驮运Piggy Back
    [USACO14JAN]滑雪等级Ski Course Rating
    [CODEVS3366] 矿石
  • 原文地址:https://www.cnblogs.com/ZengJiaLin/p/11315209.html
Copyright © 2011-2022 走看看