Иерархические роли SQL на основе ASP.NET по умолчанию RoleProvider - PullRequest
0 голосов
/ 11 февраля 2011

Я пытаюсь внести следующие корректировки в стандартный ASP.NET RoleProvider, чтобы он поддерживал иерархические определения ролей. Однако я не могу создать следующую функцию, она сохраняет Executing the function ...

Ссылка: http://mark.tremaine.net/howto/hierarchical-sql-role-provider/

Что не так с этой функцией?

    -- ================================================
    -- Template generated from Template Explorer using:
    -- Create Multi-Statement Function (New Menu).SQL
    --
    -- Use the Specify Values for Template Parameters 
    -- command (Ctrl-Shift-M) to fill in the parameter 
    -- values below.
    --
    -- This block of comments will not be included in
    -- the definition of the function.
    -- ================================================
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Author:      <Author,,Name>
    -- Create date: <Create Date,,>
    -- Description: <Description,,>
    -- =============================================


     CREATE FUNCTION [dbo].[aspnet_Roles_Ancestor_TVF] (
     @RoleId uniqueidentifier
     )
     RETURNS
     @aspnet_Roles TABLE (
     ApplicationId uniqueidentifier
     , RoleId uniqueidentifier
     , RoleName nvarchar(256)
     , LoweredRoleName nvarchar(256)
     , Description nvarchar(256)
     , ParentRoleId uniqueidentifier
     )
     AS
     BEGIN
     ; WITH aspnet_Roles_CTE (
     ApplicationId
     , RoleId
     , RoleName
     , LoweredRoleName
     , Description
     , ParentRoleId
     , HierarchyLevel
     ) AS (
     SELECT
     ApplicationId
     , RoleId
     , RoleName
     , LoweredRoleName
     , Description
     , ParentRoleId
     , 1 AS HierarchyLevel
     FROM aspnet_Roles
     WHERE RoleId = @RoleId

     UNION ALL

     SELECT
     aspnet_Roles.ApplicationId
     , aspnet_Roles.RoleId
     , aspnet_Roles.RoleName
     , aspnet_Roles.LoweredRoleName
     , aspnet_Roles.Description
     , aspnet_Roles.ParentRoleId
     , aspnet_Roles_CTE.HierarchyLevel + 1 AS HierarchyLevel
     FROM aspnet_Roles
     INNER JOIN aspnet_Roles_CTE
     ON aspnet_Roles.RoleId = aspnet_Roles_CTE.ParentRoleId
     )

     INSERT INTO @aspnet_Roles (
     ApplicationId
     , RoleId
     , RoleName
     , LoweredRoleName
     , Description
     , ParentRoleId
     )
     SELECT
     ApplicationId
     , RoleId
     , RoleName
     , LoweredRoleName
     , Description
     , ParentRoleId
     FROM aspnet_Roles_CTE
     ORDER BY HierarchyLevel

     RETURN
     END
    GO

Ответы [ 2 ]

1 голос
/ 11 февраля 2011

Я считаю, что проблема в структуре вашего CTE.Первая половина запроса Union должна представлять родителя, а вторая должна возвращать потомков.То есть вы идете по иерархии, а не по ней.Таким образом, я бы изменил предложение On во второй половине запроса Union на:

aspnet_Roles_CTE.RoleId = aspnet_Roles.ParentRoleId.

Edit

Некоторые примерыпомог бы.Вот небольшой тест, который я взбил:

Declare @RoleId int;
Set @RoleId = 1;

With aspnet_Roles As
    (
    Select 1 As ApplicationId, 1 As RoleId, 'Parent Role A' As RoleName, Null As ParentRoleId
    Union All Select 1, 2, 'Parent Role B', Null
    Union All Select 1, 3, 'Parent Role C', Null
    Union All Select 1, 4, 'Child Role A-A', 1
    Union All Select 1, 5, 'Child Role A-B', 1
    Union All Select 1, 6, 'Child Role A-C', 1
    Union All Select 1, 7, 'Child Role A-A-A', 4
    Union All Select 1, 8, 'Child Role A-A-B', 4
    Union All Select 1, 9, 'Child Role A-A-C', 4
    )
    , aspnet_Roles_CTE ( ApplicationId, RoleId, RoleName, ParentRoleId, HierarchyLevel ) As
    (
    Select ApplicationId, RoleId, RoleName, ParentRoleId, 1 AS HierarchyLevel
    From aspnet_Roles
    Where RoleId = @RoleId
    Union All
    Select AR.ApplicationId, AR.RoleId, AR.RoleName, AR.ParentRoleId, HierarchyLevel + 1
    From aspnet_Roles As AR
        Join aspnet_Roles_CTE As CTE
            On CTE.ApplicationId = AR.ApplicationId
                And CTE.RoleId = AR.ParentRoleId
     )
Select ApplicationId, RoleId, RoleName, ParentRoleId, HierarchyLevel
From aspnet_Roles_CTE

Результаты:

ApplicationId | RoleId | RoleName         | ParentRoleId | HierarchyLevel
1             | 1      | Parent Role A    | NULL         | 1
1             | 4      | Child Role A-A   | 1            | 2
1             | 5      | Child Role A-B   | 1            | 2
1             | 6      | Child Role A-C   | 1            | 2
1             | 7      | Child Role A-A-A | 4            | 3
1             | 8      | Child Role A-A-B | 4            | 3
1             | 9      | Child Role A-A-C | 4            | 3
0 голосов
/ 11 февраля 2011

Я знаю, что у CTE есть предел исчерпания рекурсии, но, может быть, у вас есть ребенок от родителя ребенка, то есть циклические отношения?

...