简体   繁体   English

ASP.NET EF6查询模型

[英]ASP.NET EF6 Query Model

I have the following model. 我有以下模型。 Each Module has a nested collection of children of type module. 每个模块都有一个嵌套的模块类型的子代集合。 Each module also has a collection of Permissions. 每个模块还具有一组权限。

[DataContract(IsReference = true)]
public class Module
{
    [Key]
    [DataMember]
    public Guid ModuleId { get; set; }

    [Required]
    [StringLength(100)]
    [DataMember]
    public string Title { get; set; }

    [StringLength(100)]
    [DataMember]
    public string Description { get; set; }

    [StringLength(50)]
    [DataMember]
    public string Icon { get; set; }

    [Required]
    [RegularExpression(@"[^\s]+")]
    [StringLength(50)]
    [DataMember]
    public string Route { get; set; }

    [DataMember]
    public ICollection<Permission> Permissions { get; set; }

    [DataMember]
    public Guid? ParentModuleId { get; set; }

    [ForeignKey("ParentModuleId")]
    [DataMember]
    public virtual ICollection<Module> Children { get; set; }
}
[DataContract(IsReference = true)]
public class Permission
{
    [Key]
    [DataMember]
    public Guid PermissionId { get; set; }

    [Required]
    [StringLength(100)]
    [DataMember]
    public string Role { get; set; }

    [DataMember]
    public Guid ModuleId { get; set; }

    [ForeignKey("ModuleId")]
    [DataMember]
    public Module Module { get; set; }
}

I have a Query All function as below, which would return correctly all root with its children. 我有一个Query All函数,如下所示,它将正确返回所有带有其子节点的root。

public override IQueryable<Module> All()
    {
        return this.Context.Set<Module>().Include(c => c.Children).Where(p => p.ParentModuleId == null);
    }

Now, I want to return same list of root with its children which has the Permission "User". 现在,我想返回具有权限“ User”的子项的相同根目录。 How do i do this. 我该怎么做呢。 This is what i have so far. 这是我到目前为止所拥有的。 Is this correct way of doing this? 这是正确的方法吗? please help. 请帮忙。

return this.Context.Set<Module>().Include(c => c.Children).Where(p => p.ParentModuleId == null).Include(p => p.Permissions).Where(s => s.Permissions.Any(r=>r.Role=="User"));

btw, i have no idea how to use properly these functions such as include,where,any,select many functions. 顺便说一句,我不知道如何正确使用这些功能,例如包含,在任何地方,选择许多功能。 Any tutorials or books for this are appreciated. 任何教程或书籍对此表示赞赏。 I can't find any good tutorial about this since i don't know what keyword to search for. 我找不到任何关于此的好的教程,因为我不知道要搜索哪个关键字。 Was this EF or LINQ. 是这个EF还是LINQ。

The Include method tells Entity Framework to go populate that specific navigational property when it goes to the database to bring back the records (ie it eager loads the data instead of utilizing lazy loading, which would require EF to go back to the database later). Include方法告诉Entity Framework在进入数据库以带回记录时填充该特定的导航属性(即,它渴望加载数据而不是利用惰性加载,这需要EF稍后再返回数据库)。 It doesn't do any kind of filtering. 它不执行任何过滤。 All that is done by the 'Where` method. 所有这些都是通过“哪里”方法完成的。

To do the kind of filtering that you're asking for across all the children you'll have to do one of two things: 要对所有孩子进行过滤,您需要做以下两件事之一:

1) Create a Common Table Expression in SQL which will recursively grab all of the children for a specific module, place that CTE in a SQL View, map an EF entity to that View, and then query that view, including a Join to the Permissions table to grab only those that have the permission you're looking for. 1)在SQL中创建一个通用表表达式,它将递归地获取特定模块的所有子级,将CTE放在SQL视图中,将EF实体映射到该视图,然后查询该视图,包括Join Permissions表格以仅获取那些具有您要查找的权限的人。

2) To do this without the T-SQL fun, simply create a recursive function on your Module class with the [NotMapped] attribute over it that will go through all of the children and return only those children that have the permission you're looking for (Note: This will require more resources than the first one, and will be slower in your application, since this will be primarily a LINQ to Objects query instead of LINQ to Entities). 2)要做到这一点而没有T-SQL的乐趣,只需在Module类上使用[NotMapped]属性创建一个递归函数,该递归函数将遍历所有子项,并仅返回那些具有您所查找权限的子项for(注意:这将比第一个需要更多的资源,并且在您的应用程序中会变慢,因为这主要是LINQ to Objects查询而不是LINQ to Entities)。

Something like this: 像这样:

[NotMapped]
public List<Module> GrabModulesWithPermission(string permission)
{
  var toReturn = new List<Module>();

  if (this.Children != null && this.Children.Any(c => c.Permissions.Any(r => r.Role == permission))
  {
     toReturn.AddRange(this.Children.Where(c => c.Permissions.Any(r => r.Role == permission).SelectMany(c => c.GrabModulesWithPermission(permission)));
  }

  toReturn.Add(this);

  return toReturn;
}

As far as tutorials go, I would highly recommend looking at Pluralsight. 就教程而言,我强烈建议您查看Pluralsight。 There are a number of videos there on EF, including some by Julie Lerman who is Microsoft's EF MVP. EF上有很多视频,其中包括Microsoft EF MVP朱莉·勒曼(Julie Lerman)的一些视频。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM