簡體   English   中英

如何使用 Dapper 存儲過程調用父子調用

[英]How to call parent child call using Dapper Stored Procedure

以下是對象結構。

public class User{
   public string Name{get;set;}
   public IList<Address> Addresss {get;set;}
   ...
}

public class Addresss{
   public string Street {get;set;}
   ...
}

使用 Dapper,如何編寫它來檢索用戶和地址列表,以及使用存儲過程調用。

試圖調用, DbConnection.QueryAsync<User>("storedprocedure",param:null,commandType:CommandType.StoredProcedure)

存儲過程查詢為, Select u.*,a.* from user u join address a on u.Id = a.UserId

預期結果為用戶列表,其中 User.Address // 應填充關聯地址列表。

我假設你的存儲過程是這樣的

SELECT u.Id, u.Name, a.UserId, a.Street FROM Users u JOIN Addresses a on u.Id = a.UserId

在這種情況下,您可以調用存儲過程並以這種方式設置地址列表的元素

Dictionary<int, User> users = new Dictionary<int, User();
var result = connection.Query<User, Address, User>(spName, ((u, a) =>
{
    if (!users.ContainsKey(u.Id))
    {
        users.Add(u.Id, u);
        u.Addresses = new List<Address>();
    }
    User k = users[b.Id];
    k.Addresses.Add(a);
    return u;
}, splitOn:"UserId", commandType:CommandType.StoredProcedure);

那么,這里發生了什么? Query 方法中的 lambda 表達式接收 Dapper 從返回的 SP 數據中提取的兩個對象(一個用戶和一個地址),並按照 splitOn 參數所述在 UserId 字段處進行拆分。
然后 lambda 會檢查字典中是否存在具有該 ID 的用戶,如果沒有,則添加用戶及其鍵,而不會忘記初始化地址列表。
在 if 之后,lambda 從字典中取回用戶並添加地址實例,最后返回作為輸入參數接收的 User 對象。 當 Dapper 完成枚舉結果時,IEnumerable 將與地址數據一起返回。

如果您期望只有 1 個用戶,那么另一種方法可能是使用 QueryMultiple,其中存儲過程必須返回 2 個數據表,第一個包含用戶信息,第二個包含用戶地址。

using (SqlConnection conn = new SqlConnection(this.DbContext.CadenaConexion))
{
    using (var results = conn.QueryMultiple($"EXEC MyStoredProcedure @userId=@userId", new { userId= 123 }))
    {
        User user = results.ReadFirst<User>();
        user.Addresses = results.Read<Address>().ToList();
        
        return user;
    }
}

存儲過程查詢如:

SELECT * FROM dbo.User WHERE Id = @userid
SELECT * FROM dbo.Address WHERE UserId = @userid

PS:我沒有運行代碼,應該不會變化太大

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM