Dapper學習(一)之Execute和Query

Dapper是一個用於.NET的簡單的對象映射,而且在速度上有着輕ORM之王的稱號。web

Dapper擴展IDbConnection,提供有用的擴展方法來查詢數據庫。sql

那麼Dapper是怎樣工做的呢?數據庫

總共三步:數組

  • 建立一個IDbConnection對象
  • 寫一個語句來執行CRUD操做
  • 傳遞語句做爲Execute方法的一個參數

由於這篇文章主要是爲了學習其中一些方法的使用,因此,這裏再也不敘述安裝等的一些使用,有須要的同窗能夠參考:https://dapper-tutorial.net/dapperapp

1.Executeide

Execute是能夠被IDbConnection類型的任何對象調用的擴展方法。它能夠執行一個命令一次或者不少次,而且返回受影響的行數。學習

這個方法能夠用於執行:大數據

  • 存儲過程(Stored Procedure)
  • 插入語句(INSERT statement)
  • 更新語句(UPDATE statement)
  • 刪除語句(DELETE statement)

下面的表格,展現了Execute方法的參數spa

 

這裏給出一個實現代碼的示例,其他部分直接在官網上的示例上面記錄學習。.net

using Dapper;
using System;
using System.Data.SqlClient;
using System.Runtime.Serialization;

namespace Dapper_Demo
{

    public class Customer
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public string About { get; set; }

        public DateTime UpdateDate { get; set; }
        
    }
    class Program
    {
        private static readonly string connectionString = @"Data Source = 127.0.0.1;Initial Catalog = DapperDemo;User Id = sa;Password = 111111;";
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var customer = new Customer { ID = 2, Name = "jack", About = "jack hh", UpdateDate = DateTime.Now };

            var Insertsql = @"insert into Customer values(@ID,@Name,@About,@UpdateDate)";

            using(var connection=new System.Data.SqlClient.SqlConnection(connectionString))
            {
                var affectedRows = connection.Execute(Insertsql,customer);
                Console.WriteLine(affectedRows);
            }

            Console.ReadKey();
        }
    }
}

注意,在使用以前,能夠nuget程序集引入Dapper和System.Data.SqlClient

下面的部分是官方代碼記錄學習。

 1.1 執行存儲過程

單次(Single)

執行一次存儲過程

string sql = "Invoice_Insert";

using (var connection = My.ConnectionFactory())
{
    var affectedRows = connection.Execute(sql,
        new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"},
        commandType: CommandType.StoredProcedure);

    My.Result.Show(affectedRows);
}

屢次(Many)

 執行存儲過程屢次。數組列表中的每一個對象執行一次

string sql = "Invoice_Insert";

using (var connection = My.ConnectionFactory())
{
    var affectedRows = connection.Execute(sql,
        new[]
        {
            new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_1"},
            new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_2"},
            new {Kind = InvoiceKind.StoreInvoice, Code = "Many_Insert_3"}
        },
        commandType: CommandType.StoredProcedure
    );

    My.Result.Show(affectedRows);
}

1.2 執行插入

單次(Single)

執行一次插入語句

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    var affectedRows = connection.Execute(sql, new {CustomerName = "Mark"});

    Console.WriteLine(affectedRows);

    var customer = connection.Query<Customer>("Select * FROM CUSTOMERS WHERE CustomerName = 'Mark'").ToList();

    FiddleHelper.WriteTable(customer);
}

屢次(Many)

執行屢次插入語句。數組列表中的每一個對象執行一次

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    connection.Open();

    var affectedRows = connection.Execute(sql,
    new[]
    {
    new {CustomerName = "John"},
    new {CustomerName = "Andy"},
    new {CustomerName = "Allan"}
    }
);

Console.WriteLine(affectedRows);

1.3 執行更新

單次(Single)

執行一次更新語句

string sql = "UPDATE Categories SET Description = @Description WHERE CategoryID = @CategoryID;";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    var affectedRows = connection.Execute(sql,new {CategoryID = 1, Description = "Soft drinks, coffees, teas, beers, mixed drinks, and ales"});

    Console.WriteLine(affectedRows);
}

屢次(Many)

執行屢次更新語句。數組列表中的每一個對象執行一次

string sql = "UPDATE Categories SET Description = @Description WHERE CategoryID = @CategoryID;";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{    
    var affectedRows = connection.Execute(sql,
    new[]
    {
    new {CategoryID = 1, Description = "Soft drinks, coffees, teas, beers, mixed drinks, and ales"},
    new {CategoryID = 4, Description = "Cheeses and butters etc."}
    }
);

Console.WriteLine(affectedRows);

1.4 執行刪除

單次(Single)

執行一次刪除語句

string sql = "DELETE FROM Customers WHERE CustomerID = @CustomerID";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    var affectedRows = connection.Execute(sql, new {CustomerID = 1});

    Console.WriteLine(affectedRows);
}

屢次(Many)

執行屢次刪除語句。數組列表中的每一個對象執行一次

string sql = "DELETE FROM OrderDetails WHERE OrderDetailID = @OrderDetailID";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    var affectedRows = connection.Execute(sql, 
        new[]
    {
    new {OrderDetailID = 1},
    new {OrderDetailID = 2},
    new {OrderDetailID = 3}
    }
);

Console.WriteLine(affectedRows);

1.5 場景說明

對於上面的execute方法在執行少許數據時,比較合適;可是若是執行數據量太大,速度就會很慢,就不適用了。下面會有對於大數據量的操做方法。

下面給出使用excute在執行批量插入數據時的一些結果。

代碼以下:

 1 using Dapper;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Data.SqlClient;
 5 using System.Diagnostics;
 6 using System.Runtime.Serialization;
 7 
 8 namespace Dapper_Demo
 9 {
10 
11     public class Customer
12     {
13         public int ID { get; set; }
14 
15         public string Name { get; set; }
16 
17         public string About { get; set; }
18 
19         public DateTime UpdateDate { get; set; }
20         
21     }
22     class Program
23     {
24         private static readonly string connectionString = @"Data Source = 127.0.0.1;Initial Catalog = DapperDemo;User Id = sa;Password = 111111;";
25         static void Main(string[] args)
26         {
27             Console.WriteLine("Hello World!");
28 
29             var list = new List<Customer>();
30             for(int i = 0; i < 100; i++)
31             {
32                 var customer = new Customer { ID = i, Name = "jack"+i, About = "jack hh"+i, UpdateDate = DateTime.Now };
33                 list.Add(customer);
34             }
35             
36 
37             var Insertsql = @"insert into Customer values(@ID,@Name,@About,@UpdateDate)";
38 
39             var stopWatch = new Stopwatch();
40             stopWatch.Start();
41             using(var connection=new System.Data.SqlClient.SqlConnection(connectionString))
42             {
43                 var affectedRows = connection.Execute(Insertsql,list);
44                 Console.WriteLine(affectedRows);
45             }
46             stopWatch.Stop();
47             Console.WriteLine("花費的時間:" + stopWatch.ElapsedMilliseconds);
48 
49             Console.ReadKey();
50         }
51     }
52 }
View Code

插入100條數據

 插入500條數據

 插入1000條數據

 能夠看出當數據量逐漸增大時,execute方法就不太適用了。

2. Query 

這個方法使用來執行查詢和映射結果的。

它的結果能夠映射到:

  • Anonymous
  • Strongly Typed
  • Multi-Mapping(One to One)
  • Multi-Mapping(One to Many)
  • Multi-Type

能夠執行的參數

2.1 Query Anonymous

Query方法能夠執行原生 SQL 查詢而且映射結果到動態集合

string sql = "SELECT TOP 10 * FROM OrderDetails";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{    
    var orderDetail = connection.Query(sql).FirstOrDefault();

    FiddleHelper.WriteTable(orderDetail);
}

2.2 Query Strongly Typed

Query方法能夠執行原生 SQL 查詢而且映射結果到強類型集合

string sql = "SELECT TOP 10 * FROM OrderDetails";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    var orderDetails = connection.Query<OrderDetail>(sql).ToList();

    Console.WriteLine(orderDetails.Count);

    FiddleHelper.WriteTable(orderDetails);
}

2.3 Query Multi-Mapping(One to One)

Query方法能夠執行原生 SQL 查詢而且用一對一的關係映射結果到強類型集合

string sql = "SELECT * FROM Invoice AS A INNER JOIN InvoiceDetail AS B ON A.InvoiceID = B.InvoiceID;";

using (var connection = My.ConnectionFactory())
{
    connection.Open();

    var invoices = connection.Query<Invoice, InvoiceDetail, Invoice>(
            sql,
            (invoice, invoiceDetail) => { invoice.InvoiceDetail = invoiceDetail; return invoice; },
            splitOn: "InvoiceID")
        .Distinct()
        .ToList();
}

2.4 Query Multi-Mapping (One to Many)

Query方法能夠執行原生 SQL 查詢而且用一對多的關係映射結果到強類型集合

string sql = "SELECT TOP 10 * FROM Orders AS A INNER JOIN OrderDetails AS B ON A.OrderID = B.OrderID;";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    var orderDictionary = new Dictionary<int, Order>();


    var list = connection.Query<Order, OrderDetail, Order>(
    sql,
    (order, orderDetail) =>
    {
        Order orderEntry;

        if (!orderDictionary.TryGetValue(order.OrderID, out orderEntry))
        {
        orderEntry = order;
        orderEntry.OrderDetails = new List<OrderDetail>();
        orderDictionary.Add(orderEntry.OrderID, orderEntry);
        }

        orderEntry.OrderDetails.Add(orderDetail);
        return orderEntry;
    },
    splitOn: "OrderID")
    .Distinct()
    .ToList();

    Console.WriteLine(list.Count);

    FiddleHelper.WriteTable(list);
    FiddleHelper.WriteTable(list.First().OrderDetails);
}

2.5 Query Multi-Type

Query方法能夠執行原生 SQL 查詢而且映射結果到有多個類型的集合

string sql = "SELECT * FROM Invoice;";

using (var connection = My.ConnectionFactory())
{
    connection.Open();

    var invoices = new List<Invoice>();

    using (var reader = connection.ExecuteReader(sql))
    {
        var storeInvoiceParser = reader.GetRowParser<StoreInvoice>();
        var webInvoiceParser = reader.GetRowParser<WebInvoice>();

        while (reader.Read())
        {
            Invoice invoice;

            switch ((InvoiceKind) reader.GetInt32(reader.GetOrdinal("Kind")))
            {
                case InvoiceKind.StoreInvoice:
                    invoice = storeInvoiceParser(reader);
                    break;
                case InvoiceKind.WebInvoice:
                    invoice = webInvoiceParser(reader);
                    break;
                default:
                    throw new Exception(ExceptionMessage.GeneralException);
            }

            invoices.Add(invoice);
        }
    }
    
    My.Result.Show(invoices);
}
相關文章
相關標籤/搜索