Dapper的基本使用


Dapper是.NET下一個micro的ORM,它和Entity Framework或Nhibnate不同,屬於輕量級的,並且是半自動的。也就是說實體類都要自己寫。它沒有復雜的配置文件,一個單文件就可以了。給出官方地址。

http://code.google.com/p/dapper-dot-net/

個人覺得他非常好用,現在已經取代了原來的SqlHelper。優點:

  1. 使用Dapper可以自動進行對象映射!
  2. 輕量級,單文件。
  3. 支持多數據庫。
  4. Dapper原理通過Emit反射IDataReader的序列隊列,來快速的得到和產生對象。

網上還有對Dapper的擴展類,這里就不贅述了。下面只講下簡單的增刪改查、數據庫表間的對應關系和事務的應用。

先給出實體類的關系:

書和書評是1---n的關系。(沿用Entity Framework的實體類,virtual表示延遲加載,此處忽略)

//public class Book  {   public Book()   {    Reviews = new List<BookReview>();   }   public int Id { get; set; }   public string Name { get; set; }   public virtual List<BookReview> Reviews { get; set; }   public override string ToString()   {    return string.Format("[{0}]------《{1}》", Id, Name);   }  } //書評 public class BookReview  {   public int Id { get; set; }   public int BookId { get; set; }   public virtual string Content { get; set; }   public virtual Book AssoicationWithBook { get; set; }   public override string ToString()   {    return string.Format("{0})--[{1}]\t\"{3}\"", Id, BookId, Content);   }  } 
  • 基本的增刪改查操作

由於Dapper ORM的操作實際上是對IDbConnection類的擴展,所有的方法都是該類的擴展方法。所以在使用前先實例化一個IDBConnection對象。

IDbConnection conn = new SqlConnection(connString);

Insert

Book book = new Book();
 book.Name="C#本質論"; string query = "INSERT INTO Book(Name)VALUES(@name)"; //對對象進行操作 conn.Execute(query, book); //直接賦值操作 conn.Execute(query, new {name = "C#本質論"});

update

string query = "UPDATE Book SET Name=@name WHERE id =@id"; conn.Execute(query, book);

delete

string query = "DELETE FROM Book WHERE id = @id"; conn.Execute(query, book); conn.Execute(query, new { id = id });

query

string query = "SELECT * FROM Book";
//無參數查詢,返回列表,帶參數查詢和之前的參數賦值法相同。
 conn.Query<Book>(query).ToList(); //返回單條信息 string query = "SELECT * FROM Book WHERE id = @id"; book = conn.Query<Book>(query, new { id = id }).SingleOrDefault();
  • 數據庫表對應關系操作
//查詢圖書時,同時查找對應的書評,並存在List中。實現1--n的查詢操作 string query = "SELECT * FROM Book b LEFT JOIN BookReview br ON br.BookId = b.Id WHERE b.id = @id"; Book lookup = null; //Query<TFirst, TSecond, TReturn> var b = conn.Query<Book, BookReview, Book>(query,   (book, bookReview) =>   {     //掃描第一條記錄,判斷非空和非重復     if (lookup == null || lookup.Id != book.Id)       lookup = book;     //書對應的書評非空,加入當前書的書評List中,最后把重復的書去掉。     if (bookReview != null)       lookup.Reviews.Add(bookReview);     return lookup;   }, new { id = id }).Distinct().SingleOrDefault(); return b;
//1--1操作 BookReview br; string query = "SELECT * FROM BookReview WHERE id = @id"; using (conn) {   br = conn.Query<BookReview, Book, BookReview>(query,   (bookReview, book) =>   {     bookReview.AssoicationWithBook = book;     return bookReview;    }, new { id = id }).SingleOrDefault();   return br; }
  • 事務操作
using (conn)
{
//開始事務 IDbTransaction transaction = conn.BeginTransaction();   try   {     string query = "DELETE FROM Book WHERE id = @id";     string query2 = "DELETE FORM BookReview WHERE BookId = @BookId";     conn.Execute(query2, new { BookId = id }, transaction, null, null);     conn.Execute(query, new { id = id }, transaction, null, null);     //提交事務     transaction.Commit();   }   catch (Exception ex)   {     //出現異常,事務Rollback     transaction.Rollback();     throw new Exception(ex.Message);   } }



Dapper.NET——輕量ORM

 

Dapper.NET使用

Dapper是一款輕量級ORM工具(Github)。如果你在小的項目中,使用Entity Framework、NHibernate 來處理大數據訪問及關系映射,未免有點殺雞用牛刀。你又覺得ORM省時省力,這時Dapper 將是你不二的選擇。

1、為什么選擇Dapper

  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

2、以Dapper(4.0)為例。

2.1 在數據庫中建立幾張表。

復制代碼
CREATE TABLE [dbo].[CICUser]
(
    [UserId]                [int] IDENTITY(1, 1) PRIMARY KEY NOT NULL,
    [Username]              [nvarchar](256) NOT NULL,
    [PasswordHash]          [nvarchar](500) NULL,
    [Email]                 [nvarchar](256) NULL,
    [PhoneNumber]           [nvarchar](30) NULL,
    [IsFirstTimeLogin]      [bit] DEFAULT(1) NOT NULL,
    [AccessFailedCount]     [int] DEFAULT(0) NOT NULL,
    [CreationDate]          [datetime] DEFAULT(GETDATE()) NOT NULL,
    [IsActive]              [bit] DEFAULT(1) NOT NULL
)

CREATE TABLE [dbo].[CICRole]
(
    [RoleId]       [int] IDENTITY(1, 1) PRIMARY KEY NOT NULL,
    [RoleName]     [nvarchar](256) NOT NULL,
)

CREATE TABLE [dbo].[CICUserRole]
(
     [Id]   [int] IDENTITY(1, 1) PRIMARY KEY NOT NULL,
     [UserId]  [int] FOREIGN KEY REFERENCES [dbo].[CICUser] ([UserId]) NOT NULL,
     [RoleId]  [int] FOREIGN KEY REFERENCES [dbo].[CICRole] ([RoleId]) NOT NULL
)
復制代碼

2.2實體類。

在創建實體類時,屬性名稱一定要與數據庫字段一一對應。

實體類

3.使用方法

3.1  一對一映射

復制代碼
 private static void OneToOne(string sqlConnectionString)
        {
            List<Customer> userList = new List<Customer>();
            using (IDbConnection conn = GetSqlConnection(sqlConnectionString))
            {
                string sqlCommandText = @"SELECT c.UserId,c.Username AS UserName,
c.PasswordHash AS [Password],c.Email,c.PhoneNumber,c.IsFirstTimeLogin,c.AccessFailedCount,
c.CreationDate,c.IsActive,r.RoleId,r.RoleName 
    FROM dbo.CICUser c WITH(NOLOCK) 
INNER JOIN CICUserRole cr ON cr.UserId = c.UserId 
INNER JOIN CICRole r ON r.RoleId = cr.RoleId";
                userList = conn.Query<Customer, Role, Customer>(sqlCommandText, 
                                                                (user, role) => { user.Role = role; return user; },
                                                                null,
                                                                null,
                                                                true, 
                                                                "RoleId", 
                                                                null,
                                                                null).ToList();
            }

            if (userList.Count > 0)
            {
                userList.ForEach((item) => Console.WriteLine("UserName:" + item.UserName +
                                                             "----Password:" + item.Password + 
                                                             "-----Role:" + item.Role.RoleName +
                                                             "\n"));

                Console.ReadLine();
            }
        }
復制代碼

3.2 一對多映射

復制代碼
private static void OneToMany(string sqlConnectionString)
        {
            Console.WriteLine("One To Many");
            List<User> userList = new List<User>();

            using (IDbConnection connection = GetSqlConnection(sqlConnectionString))
            {

                string sqlCommandText3 = @"SELECT c.UserId,
       c.Username      AS UserName,
       c.PasswordHash  AS [Password],
       c.Email,
       c.PhoneNumber,
       c.IsFirstTimeLogin,
       c.AccessFailedCount,
       c.CreationDate,
       c.IsActive,
       r.RoleId,
       r.RoleName
FROM   dbo.CICUser c WITH(NOLOCK)
       LEFT JOIN CICUserRole cr
            ON  cr.UserId = c.UserId
       LEFT JOIN CICRole r
            ON  r.RoleId = cr.RoleId";

                var lookUp = new Dictionary<int, User>();
                userList = connection.Query<User, Role, User>(sqlCommandText3,
                    (user, role) =>
                    {
                        User u;
                        if (!lookUp.TryGetValue(user.UserId, out u))
                        {
                            lookUp.Add(user.UserId, u = user);
                        }
                        u.Role.Add(role);
                        return user;
                    }, null, null, true, "RoleId", null, null).ToList();
                var result = lookUp.Values;
            }

            if (userList.Count > 0)
            {
                userList.ForEach((item) => Console.WriteLine("UserName:" + item.UserName +
                                             "----Password:" + item.Password +
                                             "-----Role:" + item.Role.First().RoleName +
                                             "\n"));

                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("No Data In UserList!");
            }
        }
復制代碼

3.3 插入實體

復制代碼
 public static void InsertObject(string sqlConnectionString)
        {
            string sqlCommandText = @"INSERT INTO CICUser(Username,PasswordHash,Email,PhoneNumber)VALUES(
    @UserName,
    @Password,
    @Email,
    @PhoneNumber
)";
            using (IDbConnection conn = GetSqlConnection(sqlConnectionString))
            {
                User user = new User();
                user.UserName = "Dapper";
                user.Password = "654321";
                user.Email = "Dapper@infosys.com";
                user.PhoneNumber = "13795666243";
                int result = conn.Execute(sqlCommandText, user);
                if (result > 0)
                {
                    Console.WriteLine("Data have already inserted into DB!");
                }
                else
                {
                    Console.WriteLine("Insert Failed!");
                }

                Console.ReadLine();
            }
        }
復制代碼

3.4 執行存儲過程

復制代碼
         /// <summary>
        /// Execute StoredProcedure and map result to POCO
        /// </summary>
        /// <param name="sqlConnnectionString"></param>
        public static void ExecuteStoredProcedure(string sqlConnnectionString)
        {
            List<User> users = new List<User>();
            using (IDbConnection cnn = GetSqlConnection(sqlConnnectionString))
            {
                users = cnn.Query<User>("dbo.p_getUsers", 
                                        new { UserId = 2 },
                                        null, 
                                        true, 
                                        null, 
                                        CommandType.StoredProcedure).ToList();
            }
            if (users.Count > 0)
            {
                users.ForEach((user) => Console.WriteLine(user.UserName + "\n"));
            }
            Console.ReadLine();
        }
復制代碼
復制代碼
        /// <summary>
        /// Execute StroedProcedure and get result from return value
        /// </summary>
        /// <param name="sqlConnnectionString"></param>
        public static void ExecuteStoredProcedureWithParms(string sqlConnnectionString)
        {
            DynamicParameters p = new DynamicParameters();
            p.Add("@UserName", "cooper");
            p.Add("@Password", "123456");
            p.Add("@LoginActionType", null, DbType.Int32, ParameterDirection.ReturnValue);
            using (IDbConnection cnn = GetSqlConnection(sqlConnnectionString))
            {
                cnn.Execute("dbo.p_validateUser", p, null, null, CommandType.StoredProcedure);
                int result = p.Get<int>("@LoginActionType");
                Console.WriteLine(result);
            }

            Console.ReadLine();
        }
 


免責聲明!

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



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