Dapper进行增删改查 z

http://www.cnblogs.com/huangkaiyan10/p/4640548.html

项目背景

     前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET、微软的EF、NH等。再跟经理讨论后,经理强调不要用 Ef,NH做ORM,后期的sql优化不好做,公司也没有人对EF,Nh 等orm优化比较熟悉的。强调说的,我们的项目要做的得简单,可以使用ADO.NET 写原始的sql。但我自己还是喜欢ORM的,它可以提高数据访问层的开发。有一天,在订阅张善友 doNet跨平台微信公众号里,看到Dapper的推荐。了解之后,我自己喜欢喜欢Dapper,可以满足我这个项目的经理的要求,同时Dapper 对数据库的访问能做到Ado.net一样快。

  下面的链接是Dapper 在github的地址  https://github.com/StackExchange/dapper-dot-net。

  使用 Dapper 进行简单增删改查示例

   1、首先根据数据库表定义实体对象, 这个工作完全可以使用T4、Nvelocity或者RazorEngine 写一个代码生成器根据数据库表对象自动生成数据库表实体对象。这里我自己根据表写了一个对象

[Table("UserRole")]
   public class UserRoleDbEntity:DbEntityModelBase
    {
        [Description("用户编号,来自用户表")]
        public int UserId
        {
            get;
            set;
        }

       [Description("角色编号,来自于角色表")]
        public int RoleId
        {
            get;
            set;
        }
        /// <summary>
        /// 备注:AuthorityEnum.AuthorityValue 的取值范围是根据 AuthorityEnum位运算 或 与 的结果集;不可随意赋值
        /// </summary>
        [Description("权限值")]
        public int AuthorityValue { get; set; }

        /// <summary>
        /// 根据 AuthorityEnum 枚举值生成的描述
        /// </summary>
        [Description("权限描述")]
        public string AuthorityDescription { get; set; }
    }

    /// <summary>
    /// 所有DbEntityModel项目中的实体必须继承DbEntityModelBase或其子类,使用supperType模式控制共有子类的行为或者状态,此项目中的类根据数据库基本表或者视图保持基本一致
    /// </summary>
   public abstract class DbEntityModelBase
    {
        [Description("Guid标识")]
        public string GuidMark
        {
            get;
            set;
        }
        [Description("自增Id列")]
        public int Id
        {
            get;
            set;
        }
       [Description("排序,倒序")]
        public int Sort
        {
            get;
            set;
        }
    }

  2. 在DAL层就可以使用实体对象传参 或者作为返回值

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OnlineExercise.DbAccess;
using Dapper;
using System.Configuration;
using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;
using OnlineExercise.DbEntityModel;
using OnlineExercise.Log;
using OnlineExercise.Infrastructrue;

namespace OnlineExercise.DbAccess.SysAdminModule
{
    public class UserRoleDB:DalBase<UserRoleDB>
    {
        public int AddUserRole(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"INSERT INTO  `userrole`
                                    (`GuidMark`,
                                     `UserId`,
                                     `RoleId`,
                                     `AuthorityValue`,
                                     `AuthorityDescription`)
                        VALUES (@GuidMark,
                                @UserId,
                                @RoleId,
                                @AuthorityValue,
                                @AuthorityDescription);";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

        public int UpdateUserRoleByRoleIdAndUserId(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"UPDATE  `userrole`
                            SET  `AuthorityValue` = @AuthorityValue,
                                `AuthorityDescription` = @AuthorityDescription
                            WHERE `UserId` = @UserId
                                AND `RoleId` = @RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

        public int UpdateUserRoleByRoleId(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"UPDATE  `userrole`
                            SET  `AuthorityValue` = @AuthorityValue,
                                `AuthorityDescription` = @AuthorityDescription
                            WHERE `RoleId` = @RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

        public int UpdateUserRoleByUserId(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"UPDATE  `userrole`
                            SET  `AuthorityValue` = @AuthorityValue,
                                `AuthorityDescription` = @AuthorityDescription
                            WHERE `UserId` = @UserId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

        public List<UserRoleDbEntity> GetUserRoleListByRoleId(UserRoleDbEntity model)
        {
            List<UserRoleDbEntity> modelList = null;
            string sql = @"SELECT
                              `Id`,
                              `GuidMark`,
                              `sort`,
                              `UserId`,
                              `RoleId`,
                              `AuthorityValue`,
                              `AuthorityDescription`
                            FROM `userrole`
                            WHERE RoleId=@RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                modelList = conn.Query<UserRoleDbEntity>(sql, model).ToList<UserRoleDbEntity>();
            }
            return modelList;
        }


        public List<UserRoleDbEntity> GetUserRoleListByUserId(string userId)
        {
            List<UserRoleDbEntity> modelList = null;
            string sql = @"SELECT
                              `Id`,
                              `GuidMark`,
                              `sort`,
                              `UserId`,
                              `RoleId`,
                              `AuthorityValue`,
                              `AuthorityDescription`
                            FROM `userrole`
                            WHERE UserId=@UserId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                modelList = conn.Query<UserRoleDbEntity>(sql, new { UserId =userId}).ToList<UserRoleDbEntity>();
            }
            return modelList;
        }

        public List<UserRoleDbEntity> GetUserRoleListByRoleIdAndUserId(UserRoleDbEntity model)
        {
            List<UserRoleDbEntity> modelList = null;
            string sql = @"SELECT
                              `Id`,
                              `GuidMark`,
                              `sort`,
                              `UserId`,
                              `RoleId`,
                              `AuthorityValue`,
                              `AuthorityDescription`
                            FROM `userrole`
                            WHERE RoleId=@RoleId and UserId=@UserId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                modelList = conn.Query<UserRoleDbEntity>(sql, model).ToList<UserRoleDbEntity>();
            }
            return modelList;
        }

        public int DeleteUserRoleByUserId(string userId)
        {
            int affecgtRow = 0;
            string sql = @"DELETE
                            FROM  `userrole`
                            WHERE `UserId` = @UserId";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, new { UserId = userId });
            }
            return affecgtRow;
        }

        public int DeleteUserRoleByRoleId(string roleId)
        {
            int affecgtRow = 0;
            string sql = @"DELETE
                            FROM  `userrole`
                            WHERE `RoleId` = @RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, new { RoleId = roleId });
                 
            }
            return affecgtRow;
        }

        public DataTable GetRoleInfoByUserId(string userId)
        {
            DataTable dt = null;

            string sql = @"SELECT b.*,a.userid,c.name as userName  FROM userrole AS a
                                INNER JOIN role AS b ON a.roleid=b.id
                                INNER JOIN USER AS c ON c.id=a.userid
                                WHERE a.userid=@userid;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                IDataReader reader = conn.ExecuteReader(sql, new { userid=userId });
                dt = CoreUtil.DataReader2Table(reader);
                reader.Dispose();
            }

            return dt;
        }

    }
}

 Dapper的优势

 1、Dapper是一个轻型的ORM类

2、 Dapper语法简单,如果你喜欢写原始的sql,你一定喜欢Dapper。同时团队人员也很容易上手

3、Dapper 速度快,速度接近ADO.NET访问数据库的效率。

4、多数据库切换方便

    public int UpdateUserRoleByRoleId(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"UPDATE  `userrole`
                            SET  `AuthorityValue` = @AuthorityValue,
                                `AuthorityDescription` = @AuthorityDescription
                            WHERE `RoleId` = @RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

这里mysql如果要切换为Sql Server ,只要修改链接  MySqlConnection---》SqlConnection。

 

Dapper更多特性

1、支持动态dynamic绑定

var rows = connection.Query("select 1 A, 2 B union all select 3, 4");

((int)rows[0].A)
   .IsEqualTo(1);

((int)rows[0].B)
   .IsEqualTo(2);

((int)rows[1].A)
   .IsEqualTo(3);

((int)rows[1].B)
    .IsEqualTo(4);
2、支持批量插入
1 connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
2     new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
3   ).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"
View Code
3、支持多表关联
var sql = 
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();

post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);
View Code

4、支持多结果查询

var sql = 
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
   var customer = multi.Read<Customer>().Single();
   var orders = multi.Read<Order>().ToList();
   var returns = multi.Read<Return>().ToList();
   ...
}
View Code
5 支持存储过程

var user = cnn.Query<User>("spGetUser", new {Id = 1}, 
        commandType: CommandType.StoredProcedure).SingleOrDefault();
// 你还可以获取存储过程out参数的输出值或者返回值
var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 

int b = p.Get<int>("@b");
int c = p.Get<int>("@c");
View Code
6、参数自动绑定

new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B 

 看到Dapper那么特性,觉得使用Dapper非常方便,使用也非常方便,扩展性也非常高。 当我用Dapper写一个demo给项目经理看的时候,项目经理就同意使用
Dapper 作为ORM 进行数据访问层的开发。从此就爱上了Dapper。
希望这篇文章给你带来对Dapper清晰的了解。

 
 

项目背景

     前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET、微软的EF、NH等。再跟经理讨论后,经理强调不要用 Ef,NH做ORM,后期的sql优化不好做,公司也没有人对EF,Nh 等orm优化比较熟悉的。强调说的,我们的项目要做的得简单,可以使用ADO.NET 写原始的sql。但我自己还是喜欢ORM的,它可以提高数据访问层的开发。有一天,在订阅张善友 doNet跨平台微信公众号里,看到Dapper的推荐。了解之后,我自己喜欢喜欢Dapper,可以满足我这个项目的经理的要求,同时Dapper 对数据库的访问能做到Ado.net一样快。

  下面的链接是Dapper 在github的地址  https://github.com/StackExchange/dapper-dot-net。

  使用 Dapper 进行简单增删改查示例

   1、首先根据数据库表定义实体对象, 这个工作完全可以使用T4、Nvelocity或者RazorEngine 写一个代码生成器根据数据库表对象自动生成数据库表实体对象。这里我自己根据表写了一个对象

  

复制代码
 1    [Table("UserRole")]
 2    public class UserRoleDbEntity:DbEntityModelBase
 3     {
 4         [Description("用户编号,来自用户表")]
 5         public int UserId
 6         {
 7             get;
 8             set;
 9         }
10 
11        [Description("角色编号,来自于角色表")]
12         public int RoleId
13         {
14             get;
15             set;
16         }
17         /// <summary>
18         /// 备注:AuthorityEnum.AuthorityValue 的取值范围是根据 AuthorityEnum位运算 或 与 的结果集;不可随意赋值
19         /// </summary>
20         [Description("权限值")]
21         public int AuthorityValue { get; set; }
22 
23         /// <summary>
24         /// 根据 AuthorityEnum 枚举值生成的描述
25         /// </summary>
26         [Description("权限描述")]
27         public string AuthorityDescription { get; set; }
28     }
29 
30     /// <summary>
31     /// 所有DbEntityModel项目中的实体必须继承DbEntityModelBase或其子类,使用supperType模式控制共有子类的行为或者状态,此项目中的类根据数据库基本表或者视图保持基本一致
32     /// </summary>
33    public abstract class DbEntityModelBase
34     {
35         [Description("Guid标识")]
36         public string GuidMark
37         {
38             get;
39             set;
40         }
41         [Description("自增Id列")]
42         public int Id
43         {
44             get;
45             set;
46         }
47        [Description("排序,倒序")]
48         public int Sort
49         {
50             get;
51             set;
52         }
53     }
复制代码

  2. 在DAL层就可以使用实体对象传参 或者作为返回值

 

View Code

   Dapper的优势

 1、Dapper是一个轻型的ORM类

2、 Dapper语法简单,如果你喜欢写原始的sql,你一定喜欢Dapper。同时团队人员也很容易上手

3、Dapper 速度快,速度接近ADO.NET访问数据库的效率。

4、多数据库切换方便

    public int UpdateUserRoleByRoleId(UserRoleDbEntity model)
        {
            int affecgtRow = 0;
            string sql = @"UPDATE  `userrole`
                            SET  `AuthorityValue` = @AuthorityValue,
                                `AuthorityDescription` = @AuthorityDescription
                            WHERE `RoleId` = @RoleId;";
            using (IDbConnection conn = new MySqlConnection(GlobalVariablesManager.G_Strconn))
            {
                affecgtRow = conn.Execute(sql, model);
            }
            return affecgtRow;
        }

这里mysql如果要切换为Sql Server ,只要修改链接  MySqlConnection---》SqlConnection。

 

Dapper更多特性

1、支持动态dynamic绑定

复制代码
 1 var rows = connection.Query("select 1 A, 2 B union all select 3, 4");
 2 
 3 ((int)rows[0].A)
 4    .IsEqualTo(1);
 5 
 6 ((int)rows[0].B)
 7    .IsEqualTo(2);
 8 
 9 ((int)rows[1].A)
10    .IsEqualTo(3);
11 
12 ((int)rows[1].B)
13     .IsEqualTo(4);
复制代码

 

2、支持批量插入
1 connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
2     new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
3   ).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"
3、支持多表关联
复制代码
 1 var sql = 
 2 @"select * from #Posts p 
 3 left join #Users u on u.Id = p.OwnerId 
 4 Order by p.Id";
 5 
 6 var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
 7 var post = data.First();
 8 
 9 post.Content.IsEqualTo("Sams Post1");
10 post.Id.IsEqualTo(1);
11 post.Owner.Name.IsEqualTo("Sam");
12 post.Owner.Id.IsEqualTo(99);
复制代码
4、支持多结果查询
复制代码
 1 var sql = 
 2 @"
 3 select * from Customers where CustomerId = @id
 4 select * from Orders where CustomerId = @id
 5 select * from Returns where CustomerId = @id";
 6 
 7 using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
 8 {
 9    var customer = multi.Read<Customer>().Single();
10    var orders = multi.Read<Order>().ToList();
11    var returns = multi.Read<Return>().ToList();
12    ...
13 } 
复制代码
5 支持存储过程
复制代码
 1 var user = cnn.Query<User>("spGetUser", new {Id = 1}, 
 2         commandType: CommandType.StoredProcedure).SingleOrDefault();
 3 // 你还可以获取存储过程out参数的输出值或者返回值
 4 var p = new DynamicParameters();
 5 p.Add("@a", 11);
 6 p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
 7 p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
 8 
 9 cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 
10 
11 int b = p.Get<int>("@b");
12 int c = p.Get<int>("@c"); 
复制代码
6、参数自动绑定
1 new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B 
   
看到Dapper那么特性,觉得使用Dapper非常方便,使用也非常方便,扩展性也非常高。 当我用Dapper写一个demo给项目经理看的时候,项目经理就同意使用

Dapper 作为ORM 进行数据访问层的开发。从此就爱上了Dapper。
希望这篇文章给你带来对Dapper清晰的了解。同时如果这文章给你到来了帮助,也别忘了帮忙推荐。
posted on 2015-07-14 18:59  武胜-阿伟  阅读(987)  评论(1编辑  收藏  举报