0

我正在尝试对默认的 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
4

2 回答 2

1

我相信问题在于您的 CTE 的结构。Union 查询的前半部分应该代表父节点,第二部分应该返回子节点。即,您正在沿着层次结构走,而不是向上走。因此,我会将 Union 查询后半部分的 On 子句更改为:

aspnet_Roles_CTE.RoleId = aspnet_Roles.ParentRoleId.

编辑

一些样本数据会有所帮助。这是我发起的一个小测试:

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

结果:

应用程序 ID | 角色 ID | 角色名 | 父角色 ID | 层级
1 | 1 | 父角色 A | 空 | 1
1 | 4 | 子角色 AA | 1 | 2
1 | 5 | 子角色 AB | 1 | 2
1 | 6 | 子角色 AC | 1 | 2
1 | 7 | 子角色 AAA | 4 | 3
1 | 8 | 子角色 AAB | 4 | 3
1 | 9 | 子角色 AAC | 4 | 3
于 2011-02-11T18:07:09.270 回答
0

我知道 CTE 有一个递归耗尽限制,但也许你有一个孩子的父母的孩子,即循环关系?

于 2011-02-11T17:16:01.293 回答