2011-02-11 57 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