2011-02-11 56 views
0

我试图对默认ASP.NET RoleProvider实施以下调整,以便它支持分层角色定义。但是我不能创建下面的函数,它使Executing the function ...基于默认ASP.NET RoleProvider的分层SQL角色

编号: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 

回答

1

我认为这个问题出现在CTE的结构中。联盟查询的前半部分应该代表父级,第二级应该返回子级。也就是说,你正在走下等级而不是它。因此,我将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 

结果:

 
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

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

+0

我还没有定义任何层次的角色呢。我只是用`Users`和`Roles`和`UsersInRoles`来运行现有数据库的代码并不奇怪......但是代码不仅仅是函数的定义,它可以在以后使用? – Ropstah 2011-02-11 20:19:48

+0

本质上。这个代码是一个函数,它说,鉴于这个角色ID,给我所有的角色,它是父母。通过“继续执行函数”,你的意思是它一遍又一遍地执行,或者它试图执行一次,并且永远不会返回? – 2011-02-11 20:34:08