ORM框架的——Dapper,Net下无敌的ORM

一样,介绍:Dapper是如出一辙暂缓轻量级ORM工具。如果您于有点之种类面临,使用Entity
Framework、NHibernate
来拍卖好数据看与关联映射,未免有点杀鸡用牛刀。你同时看ORM省时省力,这时Dapper
将凡若切莫次底取舍。

  —ORM框架的核心思想是目标关系映射,ORM是将表与发明中的操作,映射成对象同目标期间的操作,就是经过操作实体类来齐操作表的目的。从数据库提取的数据会自动按您设置的投射要求封装成特定的靶子。之后你尽管足以经对目标开展操作来改数据库被的数额。这时候若当的莫是信的零碎,而是一个像明显的目标。

仲,假如你欣赏原生的Sql语句,又喜欢ORM的简,那若早晚会爱上Dapper,这款ROMDapper的优势:

  1. 轻量。只有一个文本(SqlMapper.cs),编译完成以后只是发120k(好象是移胖了)
  2. 速快。Dapper的快接近和IDataReader,取列表的数码超过了DataTable。
  3. 支撑多数据库。Dapper可以于享有Ado.net Providers下工作,包括sqlite,
    sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
  4. 可射一对一,一对准多,多对准多等又干。
  5. 性大。通过Emit反射IDataReader的队排,来飞的得与产生对象,性能是。
  6. 支持FrameWork2.0,3.0,3.5,4.0,4.5  

脚介绍Dapper如何使用,来进展快速开发,以下操作是编译后以Net3.5产操作的例证,Net4.0下蛋大部分函数有默认值,参数很简单。

其三, 为什么要壮大Dapper?

  了解Dapper都亮,在题代码时,我们尚是碰头手动写SQL,扩展的目的就是是以全无改动dapper源代码和使用基础及,进行同样破封闭,达到零SQL,实现全对象操作。

季,原生Dapper使用流程:

  0,两种植下载应用办法:

  (1),推荐下载方式(使用Nuget下充斥):

  —Nuget是一个.NET阳台下的开源之档次,它是Visual
Studio的恢宏。在采取Visual Studio开发基于.NET
Framework的应用时,Nuget能将在路面临长、移除和创新引用的干活转移得愈加高效便利。

  图片 1

  —安装成功后,生成一下网站,项目bin目录下,会生成几个Dapper文件(主要是Dapper.dll,120k)。

  (2),可以当公网上下载Dapper源代码,即SqlMapper.cs文件,在项目中App_Code文件夹着投入这文件,就如Ado.net中的SqlHelper一样。

  —源文件地点:https://github.com/StackExchange/dapper-dot-net/blob/master/Dapper%20NET40/SqlMapper.cs

  1,下面可以于项目被起动Dapper了

  2,连接数据库字符串``。根据不同的数据库进行相应设置,如果是SQL,就类似下边设置;如果是使用SQLite,则设置方法不同。

private readonly string sqlconnection =
                 "Data Source=RENFB;Initial Catalog=test;User Id=sa;Password=sa;";
//public readonly string mysqlconnectionString =
                 @"server=127.0.0.1;database=test;uid=renfb;pwd=123456;charset='gbk'";

  3,获取Sql Server的连接数据库对象。

public SqlConnection OpenConnection()
{
    SqlConnection connection = new SqlConnection(sqlconnection); 
//这里sqlconnection就是数据库连接字符串
    connection.Open();
    return connection;
}
//获取MySql的连日数据库对象。MySqlConnection
//public MySqlConnection OpenConnection()
//{
//     MySqlConnection connection = new
MySqlConnection(mysqlconnectionString);
//     connection.Open();
//     return connection;
//}

  注:如果急需转移成Mysql数据库,只用将收获sql
Server的连接数据库对象的函数注释掉,取消MySql的连数据库对象的函数的注释,一并取消Mysql连接字符串的诠释,并修改为友好的连年信息。

  Query()方法: Query()是IDbConnection扩展方法以重载了,从数据库里提取信息,并因而来填充我们的作业对象模型。

  4,//先创造一个看似,是数据库的user表的型。
  public class user
     {
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
     }
    5,手写Sql插入数据(增)

    /// <summary>
        /// 手写Sql插入数据
        /// </summary>
        public int InsertWithSql()
        {
            using (var conn =
SQLiteHelper.OpenConnection())  //这里走访的是Sqlite数据文件,这里OpenConnection即上边获取连接数据库对象方法
            {
                user user=new user();
                user.name = “Dapper01”;
                user.address = “周口”;
                user.age=”15″;
                //string _sql = “INSERT INTO
User(name,address,age)VALUES(‘Dapper01′,’周口’,13)”;
                string _sql = “INSERT INTO
User(name,address,age)VALUES(@name,@address,@age)”;
                return conn.Execute(_sql,user);
            }
        }

    —如果不用Dapper,用插队入一修数据要有些代码量(相对上边只所以了2行代码,下边要为此6行代码):

   public static int insert_news(string title, string content)
    {
        string sql = “insert into news(title,content,addtime)
values(@title,@content,@addtime)”;
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter(“@title”,
DbType.String, title.Trim()),
                SQLiteHelper.MakeSQLiteParameter(“@content”,
DbType.String, content.Trim()),
                SQLiteHelper.MakeSQLiteParameter(“@addtime”,
DbType.DateTime,DateTime.Now)
            };
        return SQLiteHelper.ExecuteSql(sql, parameters); 
//调用SQLiteHelper文件中智,执行数据库插入
    }

6,手写Sql输出数据(删)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 15;
            DeleteColumn(user);
        }

        //删除一个品类(3行):
        public int DeleteColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “delete from user where id=@id”;
                return conn.Execute(query, user);
            }
        }

  —不用Dapper,删除一条数据,代码如下(4行):

  public static int del_news(string newid)
    {
        string sql = “delete from news where newid=@newid”;
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter(“@newid”,
DbType.String, newid.Trim())
            };
        return SQLiteHelper.ExecuteSql(sql, parameters);
    }

7,手写Sql更新数据(改)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user.name = “Dapper03”;
            user.address = “太康”;
            user.age = “25”;
            UpdateColumn(user);
        }

//更新一个色:
        public int UpdateColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “update user set
name=@name,address=@address,age=@age where id=@id”;
                return conn.Execute(query, user);
            }
        }

8,手写Sql查询数据(查)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user=SelectColumn(user.id);
           
Context.Response.Write(user.name+”|”+user.address+”|”+user.age);
            Context.Response.End();
        }

 //获取单个user对象。
        public user SelectColumn(int user_id)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “select * from user where
id=@id”;
                return conn.Query<user>(query, new {id =
user_id}).SingleOrDefault<user>(); 
//这里用之凡linq语法,所以必须引用System.Linq;
            }
        }

  —这里我们传递了一个参数为Query方法,参数可以是其它对象,其性能在查询中及sql的参数匹配,由于Query总是回到一个聚集,我们只需要调用SingleOrDefault方法,因为咱们解总是返回0或1行.

  //获取user对象的集合。
        public IEnumerable<user> SelectUsers()
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “select * from user order by id
asc”;
                return conn.Query<user>(query, null);
            }
        }

    protected void Page_Load(object sender, EventArgs e)
        {
            IEnumerable<user> list = SelectUsers();
            foreach (var i in list)
            {
                Context.Response.Write(i.name + “|” + i.address + “|” +
i.age);
                Context.Response.Write(“<br/>”);
            }
            Context.Response.End();
        }

五,如果想直接插入一个实体对象,Sql语句都不要了,可以以Nuget上下载Dapper的扩大包—>Dapper.SimpleCRUD安装包。(crud即增查改删)

  —使用Dapper.SimpleCRUD时,两个注意点,1是直接插入实体,类代码要改变:

  public class user
    {
        [Key]    //主键值前加个key
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
    }

       ///<summary>
         ///实体插入数据
         ///</summary>
        public int? InsertWithEntity()
        {
            using (var conn = SQLiteHelper.OpenConnection())
            {
                var user = new user { name = “Dapper02”, address =
“周口”,age=”22″};
                return conn.Insert(user);
            }
        } 

  —2凡使用sqlite数据库时,会报错!错误内容如下,因为sqlite不支持scope_identity函数,没有是函数:

SQL logic error or missing database no such function: SCOPE_IDENTITY

 

5,就是这么简单,直接当例子中放到Sql,很轻扩展为存储过程,可以使用别名使结果集中之排与作业对象模型(ColumnCat)的特性对应。

//下面使用上面的集合显示出分类。List<ColumnCat> AllColumnCat =SelectColumnCats().ToList<ColumnCat>();foreach (ColumnCat cat in AllColumnCat.Where(c => c.Parentid == 0)){    Response.Write("Name==>" + cat.Name + "\t");    Response.Write("时间==>" + cat.ModifiedOn + "\t");    Response.Write("<br/>");    foreach (ColumnCat c in AllColumnCat                .Where<ColumnCat>(subColumnCat => subColumnCat.Parentid == cat.Id))    {        Response.Write("&nbsp;&nbsp;++++");        Response.Write("Name==>" + c.Name + "\t");        Response.Write("时间==>" + c.ModifiedOn + "\t");        Response.Write("<br/>");    }}

//将一级类别和二级类别显示在页面上,如果使用一个递归,很容易实现无限级分类(你懂的)。

7,//Dapper也堪加载填充嵌套对象,考虑这么平等栽情况,考虑到消息的色属性,返回路对象,
//我们创建一个Column的接近
public class Column
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime ModifiedDate { get; set; }
    public ColumnCat ColumnCat { get; set; }
}

//接下我们来填充我们的政工对象。
public IList<Column> SelectColumnsWithColumnCat()
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = “select
c.Id,c.Name,c.ModifiedDate,c.ColumnCatid
        ,cat.id,cat.[Name],cat.ModifiedOn,cat.Parentid from [Column]
as c
        left outer join ColumnCat as cat on c.ColumnCatid=cat.id”;
        return conn.Query<Column, ColumnCat, Column>(query
               , (column, columncat) => { column.ColumnCat =
columncat; return column; }
               , null, null, false, “Id”, null,
null).ToList<Column>();
    }
}

  注:1,在填充嵌套对象的时段,只好执行
ToList<>方法,否则回报ExecuteReader
要求就开辟都可用之连续。连接的脚下状态也曾关门,而单个对象不见面报错,估计是using结束晚关门了连续,而嵌套对象在map的时还要实施了
ExecuteReader,只好在using结束前返回list集合。
2,嵌套对象的参数是比较多之,主要是前方少独参数,其它参数没因此好设置为null,不过以4.0版本可以独自写点儿只参数,其它参数还有默认值。特别要顾
的是splitOn,这个参数不能够吧空,否则会报对象啊援的荒谬。【splitOn参数的意思是读取第二个目标的的分割列,从哪个列起开始读取第二单针对
象,如果表里的于增长列都为Id,可以安装这个参数为”Id”】.

  Execute方法:
正如Query方法是摸索数据的,Execute方法无会见招来数据,它和Query方法十分相似,但她说到底返回总数(受影响的行数),而不是一个对象集合【如:insert
update和delete】.

8,//接下为数据库里补充加一个类
public int InsertColumnCat(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = “insert into
ColumnCat([name],ModifiedOn,Parentid)
        values (@name,@ModifiedOn,@Parentid)”;
        int row = conn.Execute(query,cat);
       
//更新对象的Id为数据库里新增的Id,假如增加后不需获得新增的目标,
        //只需要以对象上加至数据库里,可以用脚的同等履行注释掉。
        SetIdentity(conn,id=>cat.Id=id,”id”,”ColumnCat”);    
        return row;
    }
}
 
public void SetIdentity(IDbConnection conn, Action<int>
setId,string primarykey
                          ,string tableName)
{
    if (string.IsNullOrEmpty(primarykey)) primarykey = “id”;
    if (string.IsNullOrEmpty(tableName))
    {
        throw new
ArgumentException(“tableName参数不克啊空,为查询的表名”);
    }
    string query = string.Format(“SELECT max({0}) as Id FROM {1}”,
primarykey
                         , tableName);
    NewId identity = conn.Query<NewId>(query,
null).Single<NewId>();
    setId(identity.Id);
}

public class NewId
{
    public int Id { get; set; }
}

  由于Dapper是由此类似的性能自动绑定的,所以增
加了NewId类来得到增加对象后的Id,本来打算利用@@identity,Net3.5生下总是报错,只好以Max函数获取。当然如果无欲取
更新后底对象的ID,可以无使SetIdentity,这个函数通用。

编译Dapper源码生成的是Net4.0下蛋以的,可以借助Net4.0新增加的dynamic动态类型,
//SetIdentity的贯彻用死便于。如下:
public void SetIdentity<T>(IDbConnection conn, Action<int>
setId)
{
    dynamic identity = connection.Query(“SELECT @@IDENTITY AS
Id”).Single();
    T newId = (T)identity.Id;
    setId(newId);
}
9,下面介绍一下Dapper的高等级用法 
//Dapper对事务处理的例证,如剔除类别的又删除类别下的富有新闻。或者去产品之还要,
//删除产品图片表里关系的持有图片。
public int DeleteColumnCatAndColumn(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string deleteColumn = “delete from [Column] where
ColumnCatid=@catid”;
        const string deleteColumnCat = “delete from ColumnCat where
id=@Id”;

        IDbTransaction transaction = conn.BeginTransaction();
        int row=conn.Execute(deleteColumn, new { catid
=cat.Id},transaction,null,null);
        row += conn.Execute(deleteColumnCat, new {
id=cat.Id},transaction,null,null);
        transaction.Commit();
        return row;
    }
}

 

 

 

网站地图xml地图