【.NET框架】Dapper ORM 用法—Net下無敵的ORM


假如你喜歡原生的Sql語句,又喜歡ORM的簡單,那你一定會喜歡上Dapper這款ROM.點擊下載 Dapper的優勢:

1,Dapper是一個輕型的ORM類。代碼就一個SqlMapper.cs文件,編譯后就40K的一個很小的Dll.

2,Dapper很快。Dapper的速度接近與IDataReader,取列表的數據超過了DataTable。

3,Dapper支持什么數據庫。Dapper支持Mysql,SqlLite,Mssql2000,Mssql2005,Oracle等一系列的數據庫,當然如果你知道原理也可以讓它支持Mongo db

4,Dapper的r支持多表並聯的對象。支持一對多 多對多的關系。並且沒侵入性,想用就用,不想用就不用。無XML無屬性。代碼以前怎么寫現在還怎么寫。 5,Dapper原理通過Emit反射IDataReader的序列隊列,來快速的得到和產生對象。性能實在高高高。

6,Dapper支持net2.0,3.0,3.5,4.0。【如果想在Net2.0下使用,可以去網上找一下Net2.0下如何配置運行Net3.5即可。】 7,Dapper語法十分簡單。並且無須遷就數據庫的設計。

下面介紹Dapper如何使用,來進行高效開發,以下操作是編譯后在Net3.5下操作的例子,Net4.0下大部分函數有默認值,參數很簡單。

 
        
//數據庫里的表:
CREATE TABLE ColumnCat ( Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, NAME NVARCHAR(150) NULL, ModifiedOn SMALLDATETIME NULL DEFAULT(GETDATE()), Parentid INT ) CREATE TABLE Column ( Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, NAME NVARCHAR(150) NULL, ModifiedDate SMALLDATETIME NULL DEFAULT(GETDATE()), ColumnCatid INT null )


常用的表,分類和內容表,分類可以有下級類別。以下操作基本上都是對這兩個表的操作。
//連接數據庫字符串。
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'";
//獲取Sql Server的連接數據庫對象。SqlConnection 
public SqlConnection OpenConnection() { SqlConnection connection = new 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擴展方法並且重載了,從數據庫里提取信息,並用來填充我們的業務對象模型。

 
        
//先創建一個類,是數據庫的ColumnCat表的模型。
public class ColumnCat { public int Id { get; set; } public string Name { get; set; } public DateTime ModifiedOn { get; set; } public int Parentid { get; set; } } //獲取ColumnCat對象的集合。
public IEnumerable<ColumnCat> SelectColumnCats() { using (IDbConnection conn = OpenConnection()) { const string query = "select * from ColumnCat order by id desc"; return conn.Query<ColumnCat>(query,null); } }
 
        

就是這么簡單,直接在例子中嵌入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/>"); } }
//將一級類別和二級類別顯示在頁面上,如果使用一個遞歸,很容易實現無限級分類(你懂的)。 

 

 
//獲取單個ColumnCat對象。
public ColumnCat SelectColumnCat(int columnCatId) { using (IDbConnection conn = OpenConnection()) { const string query = "select * from ColumnCat where Id=@id"; return conn.Query<ColumnCat>(query, new { id=columnCatId}) .SingleOrDefault<ColumnCat>(); } }

 

這里我們傳遞了一個參數給Query方法,參數可以是任何對象,其屬性在查詢中與sql的參數匹配,由於Query總是返回一個集合,我們只需調用SingleOrDefault方法,因為我們知道總是返回0或1行.

 
        
//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】.

//接下來向數據庫里添加一個類別
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); } //更新一個類別:
public int UpdateColumnCat(ColumnCat cat) { using (IDbConnection conn = OpenConnection()) { const string query = "update ColumnCat set name=@Name
                          ,ModifiedOn=@ModifiedOn,Parentid=@Parentid where Id=@id";
        return conn.Execute(query,cat); } } //刪除一個類別:
public int DeleteColumnCat(ColumnCat cat) { using (IDbConnection conn = OpenConnection()) { const string query = "delete from ColumnCat where id=@id"; return conn.Execute(query, cat); } } 下面介紹一下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; } }

 

原文【http://www.renfb.com/blog/2011/Article/335


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM