溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

發(fā)布時間:2020-08-29 14:39:01 來源:腳本之家 閱讀:192 作者:省厓 欄目:編程語言

前言

對象關(guān)系映射(ORM)已經(jīng)被使用了很長時間,以解決在編程過程中對象模型與數(shù)據(jù)模型在關(guān)系數(shù)據(jù)庫中不匹配的問題。

Dapper是由Stack OverFlow團(tuán)隊開發(fā)的開源的,輕量級的ORM.相比于其他的ORM框架,Dapper速度非???。

Dapper的設(shè)計考慮到了性能以及易用性。它支持使用事務(wù),存儲過程或數(shù)據(jù)批量插入的靜態(tài)和動態(tài)對象綁定。

在本文中,我們將介紹如何使用DAPPER從單個數(shù)據(jù)庫調(diào)用中讀取數(shù)據(jù)庫中的多個結(jié)果集。我們將看看我們可能希望這樣做的場景,以及如何使用它的Query和QueryMultiple方法更簡潔地實現(xiàn)這一點。 當(dāng)我們談?wù)撘詳?shù)據(jù)為中心的應(yīng)用程序時,可能會出現(xiàn)一些場景,在這些場景中我們可能希望從數(shù)據(jù)庫中檢索多重結(jié)果。多個結(jié)果集既可以是相關(guān)的,也可以是無關(guān)的。要做到這一點,我們不需要對數(shù)據(jù)庫進(jìn)行多次往返,而是可以在一次數(shù)據(jù)庫調(diào)用本身中實際使用dapper檢索結(jié)果,然后將結(jié)果映射到代碼中的所需對象。

在我們繼續(xù)并開始研究如何做到這一點之前,讓我們首先試著理解在我們的應(yīng)用程序中可能希望做到這一點的場景:

1、查詢無關(guān)實體:所請求的實體根本不相關(guān)。

2、查詢具有1至多個關(guān)系的相關(guān)實體:被請求的實體具有1對多的關(guān)系,我們需要在代碼中處理多個結(jié)果集

3、查詢具有1至1關(guān)系的相關(guān)實體:被請求的實體具有1-1關(guān)系,我們需要在代碼中執(zhí)行處理多個映射 在第一個場景中,我們有完全不相關(guān)的實體,因此基本上,我們只想執(zhí)行兩個獨立的查詢來檢索數(shù)據(jù),然后將其映射到這些實體。在第二個場景中,返回的實體與1-多相關(guān),因此我們希望檢索數(shù)據(jù),然后將結(jié)果映射到具有1至多個關(guān)系的POCO中。

最后,在第三個場景中,返回的實體是1-1,因此我們希望檢索數(shù)據(jù),然后將結(jié)果映射到具有1-1關(guān)系的POCO中。 現(xiàn)在讓我們看看一些代碼,了解如何使用Dapper來實現(xiàn)這一切。 所有這些都可以通過DAPPER的查詢、QueryMultiple和Read方法進(jìn)行歸檔?,F(xiàn)在讓我們把重點放在如何在代碼中執(zhí)行這些操作。

查詢無關(guān)實體

假設(shè)我們想從API中檢索書籍和視頻列表。我們可以通過兩個簡單的選擇所有查詢來實現(xiàn)這一點,數(shù)據(jù)庫結(jié)果看起來如

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

現(xiàn)在,為了能夠從代碼中執(zhí)行同樣的操作,我們首先需要定義我們的實體:

public class Book
{
 public int ID { get; set; }
 public string BookName { get; set;}
 public string ISBN { get; set; }
}

public class Video
{
 public int ID { get; set; }
 public string VideoName { get; set; }
}

使用這些模型,讓我們看看如何只使用一個數(shù)據(jù)庫調(diào)用來使用DAPPER檢索這些結(jié)果:

public IActionResult Index()
{
 // define our SQL query - it contains mulitple queries seprated by ;
 var query = "SELECT * from Books; Select * from Videos";

 // Execute the query
 var results = dbConnection.QueryMultiple(query);

 // retrieve the results into the respective models
 var books = results.Read<Book>();
 var videos = results.Read<Video>();

 return Ok(new { Books = books, Videos = videos});
}

現(xiàn)在讓我們在POSTMAN中運行,以查看行動中的結(jié)果:

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

注意:我已經(jīng)創(chuàng)建了一個簡單的API控制器來測試這個代碼,所有的DB訪問代碼都在里面運行。這只是為了演示目的和現(xiàn)實世界的應(yīng)用,這樣的代碼根本不應(yīng)該被使用。

查詢具有1到多關(guān)系的查詢相關(guān)實體

檢索相關(guān)實體的另一個典型場景是實體之間存在一對多關(guān)系。讓我們嘗試使用組織和聯(lián)系人的例子來可視化這一點。組織通常具有與其關(guān)聯(lián)的多個聯(lián)系人。如果我們想要檢索一個組織,并且想要檢索所有關(guān)聯(lián)的聯(lián)系人,我們可以利用QueryMultiple來做到這一點。這就是關(guān)系在數(shù)據(jù)庫中的樣子。

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

首先讓我們檢查一下如何使用SQL查詢做同樣的操作。

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

現(xiàn)在,如果我們必須在代碼中做同樣的事情,我們首先需要定義我們的實體。請注意,我們的實體也將建模一對多關(guān)系的方式,每個組織有一個聯(lián)系人列表。

public class Organization
{
 public int ID { get; set; }
 public string OrganizationName { get; set; }

 public List<contact> Contacts { get; set; }
}

public class Contact
{
 public int ID { get; set; }
 public int OrganizationId { get; set; }
 public string ContactName { get; set; }
}
</contact>

現(xiàn)在讓我們看一下用于檢索這些相關(guān)實體的代碼,并了解如何用dapper的QueryMultiple方法填充與1到多個關(guān)系相關(guān)的實體。

[HttpGet("{id}")]
public IActionResult GetOrganization(int id)
{
 // define our SQL query - it contains mulitple queries seprated by ;
 var query = @"SELECT* from Organizations where id = @id;
    Select * from Contacts where OrganizationId = @id";

 // Execute the query
 var results = dbConnection.QueryMultiple(query, new { @id = id });

 // retrieve the results into the respective models
 var org = results.ReadSingle<Organization>();
 org.Contacts = results.Read<Contact>().ToList();

 return Ok(org);
}

在上面的代碼中,我們可以看到我們是如何同時執(zhí)行2個查詢的。我們接受了第一個查詢結(jié)果并填充了我們的組織對象。第二個查詢結(jié)果作為同一個組織對象的聯(lián)系人集合被推送。

現(xiàn)在讓我們在POSTMAN中運行,以查看行動中的結(jié)果:

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

具有1到1關(guān)系的查詢相關(guān)實體

前兩個場景非常簡單,因為它們要求我們編寫兩個獨立的查詢,然后獨立收集每個查詢的結(jié)果,以便根據(jù)需要創(chuàng)建模型對象。

但是有1到1個關(guān)系的場景是很棘手的。從數(shù)據(jù)庫的角度來看,我們可以在單個SQL查詢本身中檢索相關(guān)實體,但是隨后我們希望將單個結(jié)果集映射到代碼中的多個對象中。這可以使用在DAPPER中可用的多重映射特征來完成。讓我們在一個例子的幫助下理解這一點。

注意:我們?nèi)匀豢梢允褂门c1到許多關(guān)系相同的方法來檢索與1到1相關(guān)的數(shù)據(jù),但是本節(jié)將展示如何使用單個SQL并映射結(jié)果。

讓我們舉一個聯(lián)系和護(hù)照的例子。每個聯(lián)系人只能有一個護(hù)照。讓我們先想象一下這個數(shù)據(jù)庫關(guān)系。

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

現(xiàn)在,讓我們看看是否需要從數(shù)據(jù)庫中檢索聯(lián)系人列表及其護(hù)照信息,我們?nèi)绾斡肧QL實現(xiàn)這一點。

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

現(xiàn)在讓我們看看我們的實體如何尋找聯(lián)系和護(hù)照。

public class Contact
{
 public int ID { get; set; }
 public int OrganizationId { get; set; }
 public string ContactName { get; set; }

 public Passport Passport { get; set; }
}

public class Passport
{
 public int ID { get; set; }
 public int Contactid { get; set; }
 public string PassportNumber { get; set; }
}

現(xiàn)在讓我們看看如何從數(shù)據(jù)庫中檢索這些相關(guān)實體,并使用更簡潔的多重映射完整地填充具有相同關(guān)系的POCOs。

[HttpGet("{id}")]
public IActionResult GetContact(int id)
{
 var query = @"Select
    c.ID, c.Organizationid, c.ContactName,
    p.ID as PassPortId, p.ContactId, p.PassportNumber
    from Contacts c,
    Passports p
    where c.ID = p.ContactID
    and c.id = @id";

 // Execute the query
 var contact = dbConnection.Query<Contact, Passport, Contact>(query, MapResults, new { @id = id }, splitOn: "PassportId");

 return Ok(contact);
}

private Contact MapResults(Contact contact, Passport passport)
{
 contact.Passport = passport;
 return contact;
}

在上面的代碼中,我們使用的是查詢方法的重載版本,它采用多個類型。傳遞的類型是我們要映射的每個對象的類型參數(shù),最后一個類型參數(shù)是表示該查詢將返回的對象類型的附加參數(shù)。

因此,在我們的查詢中,我們希望將結(jié)果映射到類型Contact和Passsport,然后期望結(jié)果返回到類型Contact的對象中。

現(xiàn)在,讓我們看看在查詢方法中傳遞的實際參數(shù)。

第一個參數(shù)是SQL查詢本身。

第二個參數(shù)是映射函數(shù),它將獲取結(jié)果,將它綁定到相應(yīng)的類型,然后創(chuàng)建所需的返回類型并返回該返回類型。在我們的代碼中,它采用Contact和Passport類型,并將Contact的Passport屬性指定為正在傳遞的Passport值。一旦這樣做,結(jié)果接觸類型返回。

第三個參數(shù)是命令參數(shù)@ id。

最后一個參數(shù)拆分是將告訴DAPPER哪些列必須映射到下一個對象的列名。在我們的示例中,我們將此值作為PassportId傳遞,這意味著在找到PassportId列之前,所有列都將映射到第一種類型,即Contact,然后隨后的列將被映射到下一個參數(shù)類型,即Passport。

注意:如果我們有2個以上的對象需要映射,splitOn將是一個逗號分隔的列表,其中每個列名將充當(dāng)分隔符,并開始下一個對象類型的映射列。

現(xiàn)在讓我們在POSTMAN中運行,以查看行動中的結(jié)果:

如何使用Dapper處理多個結(jié)果集與多重映射實例教程

歐了,我們使用DAPPER從數(shù)據(jù)庫中檢索多個結(jié)果集,以避免數(shù)據(jù)庫往返。

總結(jié):

在本文中,我們討論了如何使用dapper提供的特性在一次運行中檢索多個相關(guān)或無關(guān)的實體,從而避免多次數(shù)據(jù)庫往返。這是從初學(xué)者的角度寫的。我希望這有一定的信息性。

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI