Как вызвать родительский дочерний вызов с помощью хранимой процедуры Dapper - PullRequest
0 голосов
/ 28 февраля 2020

Ниже приведена структура объекта.

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 // должен заполняться списком связанных адресов.

Ответы [ 2 ]

2 голосов
/ 28 февраля 2020

Я предполагаю, что ваша хранимая процедура выглядит примерно так

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);
* 1006 Итак, что здесь происходит? Лямбда-выражение в методе Query получает два объекта (A User и Address), извлеченных Dapper из возвращенных данных SP и разделенных в поле UserId, как указано в параметре splitOn.
Затем lambda проверяет, есть ли пользователь с этим Id внутри словаря и, если нет, добавляет пользователя с его ключом, не забывая инициализировать список адресов.
После if лямбда возвращает пользователя из словаря и добавляет экземпляр адреса, наконец возвращает Пользовательский объект получен в качестве входного параметра. Когда Dapper заканчивает перечислять результаты, возвращается IEnumerable с данными Address на месте.
1 голос
/ 28 февраля 2020

Если вы ожидаете, что только 1 пользователь, возможно, другой подход мог бы использовать QueryMultiple, хранимая процедура должна возвращать 2 DataTables, первый с информацией о пользователе, а второй с адресами пользователя.

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.Addresss.Clientes = results.Read<Addresss>().ToList();

        return user;
    }
}

Хранимая процедура запрос вроде:

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

PS: я не запускал код, он не должен сильно отличаться

...