在Dapper QueryMultiple中首次选择的访问结果(多对多)

问题描述 投票:2回答:1

我正在尝试将多对多的关系映射到具有角色列表的用户

我尝试做这个问题Dapper Many-to-Many Query,但它给了我多个用户每个单一的角色。

相反,我正在尝试使用QueryMultiple语句。我的问题是我从电子邮件中查询用户,但需要从用户的ID中查询角色。所以我需要访问第一个查询语句的结果,将Id传递给第二个。我怎样才能做到这一点?

        public async Task<User> GetUserByEmailAsync(string email, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new SqlConnection(_options.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var results = await connection.QueryMultipleAsync(@"SELECT * FROM [User] WHERE Email = @email; " +
            "SELECT Id, Name, NormalizedName FROM [Role] JOIN [UserRole] ON [Role].Id = UserRole.RoleId" +
            " WHERE [UserRole].UserId = 2",  // <-- NEED TO INSERT USER ID DYNAMICALLY HERE
            new
            {
                email
            });

            var user = await results.ReadSingleAsync<User>();
            var roles = await results.ReadAsync<Role>();

            foreach (var role in roles)
            {
                user.Roles.Add(role);
            }

            return user;
        }
    }
c# .net dapper
1个回答
3
投票

目前无法对其进行全面测试,但您可以使用此方法为特定用户填充所有角色,从而获得单个用户。

public async Task<User> UserFromEmail(string email)
{
    Dictionary<int, User> result = new Dictionary<int, User>();

    string query = @"
            SELECT u.*, r.*
            FROM [User] u JOIN [UserRole] ur on u.UserId = ur.UserId
                          JOIN [Roles] r on ur.RoleId = r.Id
            WHERE u.Email = @email;";
    using (IDbConnection cnn = OpenConnection())
    {
        var users = await cnn.QueryAsync<User, Role, User>(query, (u, r) =>
        {
            // this lambda is called for each record retrieved by Dapper
            // receiving a user and a role created by Dapper from the record
            // and it is expected to return a user.
            // We look if the user passed in is already in the dictionary 
            // and add the role received to the roles list of that user
            if (!result.ContainsKey(u.UserId))
                result.Add(u.UserId, u);
            User working = result[u.UserId];
            working.roles.Add(r);
            return u;
        }, new { email }, splitOn: "RoleId");

        // Return the first element in the dictionary
        if (result.Values.Count > 0)
            return result.Values.First();
        else
            return null;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.