递归选择父级(对于ACL /权限系统)

时间:2014-12-19 14:54:35

标签: c# sql-server linq entity-framework

重要的事情

型号Category

[Table("Category")]
public class Category
{
    public Category()
    {
        Children = new HashSet<Category>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Column("Parent")]
    public int? ParentId { get; set; }
    [ForeignKey("ParentId")]
    public virtual Category Parent { get; set; }
    public virtual ICollection<Category> Children { get; set; }

    public string Name { get; set; }
}

数据库条目:

---------------------------------
| Id | Parent | Name            |
---------------------------------
|  1 |   NULL | Top Category    |
---------------------------------
|  2 |    1   | Second Category |
---------------------------------
|  3 |    2   | Third Category  |
---------------------------------
|  4 |    3   | Fifth Category  |
---------------------------------

现在问题......

我如何使用像...这样的查询

SELECT "Name" FROM "Category" WHERE "Parent" IS NULL;

,查询类似......

SELECT "c"."Id", "c"."Parent", "p"."Name" FROM "Category" "c" LEFT JOIN "Category" "p" ON "p"."Id" = "c"."Parent" WHERE "c"."Name" LIKE '%d%';

我想以递归的方式选择所有父母的类别。 为此提供LINQ查询真的很不错。

预期结果如下:

----------------------------------------------
| "c"."Id" | "c"."Parent" | "p"."Name"       |
----------------------------------------------
|    2     |    1         | Top Category     |
----------------------------------------------
|    3     |    2         | Second Category  |
----------------------------------------------

或与群组合作?

-----------------------------------------------------------
| "c"."Id" | "c"."Parent" | GROUP_CONCAT(...)             |
-----------------------------------------------------------
|     2, 3 |         1, 2 | Top Category, Second Category |
-----------------------------------------------------------

类别&#34;系统&#34;以上是更大计划的一个例子......:

(是否有框架/ nuget插件允许对存储在数据库中的对象使用ACL /权限/权限? 我有用户和组。然后我有文件夹和文件。每个用户或组都可以拥有特定文件夹或文件的权限。您可以为文件或文件夹权限启用遗传。使用此查询,我尝试读取用户和所有父母的特定文件夹的所有权限...)

1 个答案:

答案 0 :(得分:0)

尝试此查询

 var result = 
        from first in db.Category
        join second in db.Category on first.Id equals second.ParentId.GetValueOrDefault(0) 
        where first.name.Contains(parameter)
        select new
        { 
            Id = first.Id , 
            ParentId= second.ParentId ?? 0, 
            ParentName= second.Name
        };

我使用了second.ParentId.GetValueOrDefault(0),因为连接是在两个不同的类型int和nullable of int

上进行的