简体   繁体   English

如何使用 Dapper 存储过程调用父子调用

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

Following is the object structure.以下是对象结构。

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

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

Using Dapper, how this can be written to retrieve User along with List Of Address and that's using Stored Procedure call.使用 Dapper,如何编写它来检索用户和地址列表,以及使用存储过程调用。

Trying to call like, DbConnection.QueryAsync<User>("storedprocedure",param:null,commandType:CommandType.StoredProcedure)试图调用, DbConnection.QueryAsync<User>("storedprocedure",param:null,commandType:CommandType.StoredProcedure)

Stored Procedure query is as, Select u.*,a.* from user u join address a on u.Id = a.UserId存储过程查询为, Select u.*,a.* from user u join address a on u.Id = a.UserId

Expected result as List Of Users where User.Address // should populate with list of associated address.预期结果为用户列表,其中 User.Address // 应填充关联地址列表。

I assume that your stored procedure is something like this我假设你的存储过程是这样的

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

In this case you could call the stored procedure and set the elements of the Address list in this way在这种情况下,您可以调用存储过程并以这种方式设置地址列表的元素

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);

So, what's happens here?.那么,这里发生了什么? The lambda expression in the Query method receives two objects (A User and an Address) extracted by Dapper from the returned SP data and splitted at the UserId field as stated by the splitOn parameter. Query 方法中的 lambda 表达式接收 Dapper 从返回的 SP 数据中提取的两个对象(一个用户和一个地址),并按照 splitOn 参数所述在 UserId 字段处进行拆分。
The lambda then checks if there is a user with that Id inside the dictionary and, if not, adds the User with its key without forgetting to initialize the address list.然后 lambda 会检查字典中是否存在具有该 ID 的用户,如果没有,则添加用户及其键,而不会忘记初始化地址列表。
After the if, the lambda gets back the user from the dictionary and adds the address instance, finally returns the User object received as input parameter.在 if 之后,lambda 从字典中取回用户并添加地址实例,最后返回作为输入参数接收的 User 对象。 When Dapper finishes to enumerate the results the IEnumerable is returned with the Address data in place.当 Dapper 完成枚举结果时,IEnumerable 将与地址数据一起返回。

If you expect just 1 user maybe another approach could be using QueryMultiple which the stored procedure must return 2 DataTables, the first with the user info and the second with the user addresses.如果您期望只有 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;
    }
}

Stored procedure query like :存储过程查询如:

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

PS: I didn't run the code, it should not vary too much PS:我没有运行代码,应该不会变化太大

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM