iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
2
Software Development

🌊 進階學習 ADO.NET、Dapper、Entity Framework 系列 第 13

【深入Dapper.NET源碼】Query Multi Mapping 使用方式

接著講解Dapper Multi Mapping(多對應)實作跟底層邏輯,畢竟工作當中不可能都是一對一概念。

使用方式 :

  • 需要自己編寫Mapping邏輯,使用方式 : Query<Func邏輯>(SQL,Parameter,Mapping邏輯Func)
  • 需要指定泛型參數類別,規則為Query<Func第一個類別,Func第二個類別,..以此類推,Func最後返回類別> (最多支持六組泛型參數)
  • 指定切割欄位名稱,預設使用ID,假如不一樣需要特別指定 (這段後面特別講解)
  • 以上順序都是由左至右

舉例 : 有訂單(Order)跟會員(User)表格,關係是一對多關係,一個會員可以有多個訂單,以下是C# Demo代碼 :

void Main()
{
	using (var ts = new TransactionScope())
	using (var cn = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=SSPI;Initial Catalog=master;"))
	{
		cn.Execute(@"
			CREATE TABLE [User]([ID] int, [Name] nvarchar(10));
			INSERT INTO [User]([ID], [Name])VALUES(1, N'大雄'),(2, N'小明');

			CREATE TABLE [Order]([ID] int, [OrderNo] varchar(13), [UserID] int);
			INSERT INTO [Order]([ID], [OrderNo], [UserID])VALUES(1, 'SO20190900001', 1),(2, 'SO20190900002', 1),(3, 'SO20190900003', 2),(4, 'SO20190900004', 2);
		");

		var result = cn.Query<Order,User,Order>(@"
				select * from [order] T1
				left join [User] T2 on T1.UserId = T2.ID		
			", (order, user) => { 
				order.User = user;
				return order;
			}
		);
		
		ts.Dispose();
	}
}

public class Order
{
	public int ID { get; set; }	
	public string OrderNo { get; set; }	
	public User User { get; set; }	
}

public class User
{
	public int ID { get; set; }
	public string Name { get; set; }
}

20191001145311.png


支援dynamic Multi Mapping

在初期常變動表格結構或是一次性功能不想宣告Class,Dapper Multi Mapping也支援dynamic方式

void Main()
{
	using (var ts = new TransactionScope())
	using (var connection = Connection)
	{
		const string createSql = @"
            create table Users (Id int, Name nvarchar(20))
            create table Posts (Id int, OwnerId int, Content nvarchar(20))

            insert Users values(1, N'小明')
            insert Users values(2, N'小智')

            insert Posts values(101, 1, N'小明第1天日記')
            insert Posts values(102, 1, N'小明第2天日記')
            insert Posts values(103, 2, N'小智第1天日記')
		";
		connection.Execute(createSql);

		const string sql =
			@"select * from Posts p 
			left join Users u on u.Id = p.OwnerId 
			Order by p.Id
		";

		var data = connection.Query<dynamic, dynamic, dynamic>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
	}
}

20191002023135.png

SplitOn區分類別Mapping組別

Split預設是用來切割主鍵,所以預設切割字串是Id,假如當表格結構PK名稱為Id可以省略參數,舉例
20191001151715.png

var result = cn.Query<Order,User,Order>(@"
	select * from [order] T1
	left join [User] T2 on T1.UserId = T2.ID		
	", (order, user) => { 
		order.User = user;
		return order;
	}
);

假如主鍵名稱是其他名稱,請指定splitOn字串名稱,並且對應多個可以使用,做區隔,舉例,添加商品表格做Join :

var result = cn.Query<Order,User,Item,Order>(@"
	select * from [order] T1
	left join [User] T2 on T1.UserId = T2.ID	
	left join [Item] T3 on T1.ItemId = T3.ID
	"
	
	,map :  (order, user,item) => { 
		order.User = user;
		order.Item = item;
		return order;
	}
	,splitOn : "Id,Id"
);

上一篇
【深入Dapper.NET源碼】Dapper SQL正確字串拼接方式 : Literal Replacement
下一篇
【深入Dapper.NET源碼】Query Multi Mapping 底層原理
系列文
🌊 進階學習 ADO.NET、Dapper、Entity Framework 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言