从单个数据行中的列创建KeyValuePair <tkey,tvalue =“”>

时间:2016-08-02 02:58:38

标签: sql-server asp.net-identity dapper

我在Sql Server中有以下表,它存储外键UserId对外键BlogId的权限。我想要做的是使用Dapper编写一个查询,在BlogId之后获取每一列并将其作为KeyValuePair<TKey, TValue>返回。

CREATE TABLE [dbo].[UserPermission] (
    [UserPermissionId]     INT IDENTITY (1, 1) NOT NULL,
    [BlogId]               INT NOT NULL,
    [UserId]               INT NOT NULL,
    [CanCreateNewPosts]    BIT NOT NULL,
    [CanEditExistingPosts] BIT NOT NULL,
    [CanDeleteExistingPosts] BIT NOT NULL,
    [CanPublishDraftPosts] BIT NOT NULL,
    CONSTRAINT [PK_UserPermission] PRIMARY KEY CLUSTERED ([UserPermissionId] ASC),
    CONSTRAINT [FK_UserPermission_Blog] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blog] ([BlogId]),
    CONSTRAINT [FK_UserPermission_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([UserId])
);

我想通过Dapper查询:

using (var connection = new SqlConnection(this.connectionString))
{
    string sql = "SELECT * FROM [Permission] WHERE UserId = @UserId";
    await connection.OpenAsync();
    IEnumerable<KeyValuePair<string, bool>> results = await connection.QueryAsync(
        sql,
        new { UserId = this.userId });
}

var p1 = results.First();
var p2 = results.Skip(1).First();

在上面的示例中,我希望p1生成一个KeyValuePair,其中Key为CanCreateNewPosts,而Value为列值,为true或false。同样适用于p2,其中密钥为CanEditExistingPosts,其中包含相应的值。

对此的基本需求是简化将记录转换为身份中的声明列表,每列一个声明。

我查看splitOn:,尝试在UserId列之后进行拆分,但这看起来并不像我想要的那样。对于我拆分的每一列,它需要n个泛型参数。理想情况下,我希望将来在此表中添加列,而我的安全/数据/服务层只是处理将其转换为声明 - 让我只关注需要检查声明的Controller Action。让查询和Dapper返回映射列名称/值到KeyValuePairs的集合将有助于我。

1 个答案:

答案 0 :(得分:0)

您可以使用SQL UNPIVOT操作将列转换为列值。以下是您的具体案例的示例:

SELECT u.BlogId, u.permission
FROM UserPermissions up
UNPIVOT
(
    permission for perms in (
        CanCreateNewPosts, 
        CanEditExistingPosts, 
        CanDeleteExistingPosts, 
        CanPublishDraftPosts
    )
) u;