【问题标题】:Entity Framework Code First Tree Model实体框架代码优先树模型
【发布时间】:2013-08-23 08:36:46
【问题描述】:

我有以下实体:

public class Module
{
    public Module()
    {
        SubModules = new List<Module>();
    }

    public int Id { get; set; }
    public string Title { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public string Icon { get; set; }

    public List<Module> SubModules { get; set; }
}

其中,通过 Code First 初始化时会生成下表 Schema:

CREATE TABLE [dbo].[Modules](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Title] [nvarchar](max) NULL,
    [Action] [nvarchar](max) NULL,
    [Controller] [nvarchar](max) NULL,
    [Icon] [nvarchar](max) NULL,
    [Module_Id] [int] NULL,
 CONSTRAINT [PK_dbo.Modules] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
)

GO
ALTER TABLE [dbo].[Modules]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Modules_dbo.Modules_Module_Id] FOREIGN KEY([Module_Id])
REFERENCES [dbo].[Modules] ([Id])
GO
ALTER TABLE [dbo].[Modules] CHECK CONSTRAINT [FK_dbo.Modules_dbo.Modules_Module_Id]
GO

问题是,当我用一个父模块(Module_Id 为 null)和两个子模块(父模块的 Module_Id)填充此表并查询 DBContext 的模块集合时,我得到父模块及其子模块的集合模块正确,但我也得到自己返回的子模块。

所以 DbContext 中的 Modules 集合看起来有点像这样:

ParentModule
---Child Module
---Child Module
Child Module
Child Module

我需要的是让这两个子模块本身不作为模块返回,而仅作为父模块的子模块返回。

希望我已经解释清楚了。

【问题讨论】:

    标签: ef-code-first entity-framework-5


    【解决方案1】:

    我会将 ParentModuleId 属性 (int?) 添加到您的 Module 类中。

    public class Module
    {
        public Module()
        {
            SubModules = new List<Module>();
        }
    
        public int Id { get; set; }
        public string Title { get; set; }
        public string Action { get; set; }
        public string Controller { get; set; }
        public string Icon { get; set; }
    
        public int? ParentModuleId { get; set; }
    
        [ForeignKey("ParentModuleId")]
        public virtual ICollection<Module> SubModules { get; set; }
    }
    

    请注意,我还在 SubModules 列表中添加了 ForeignKey 属性,以确保将新的 ParentModuleId 属性用作外键列。

    这样您可以手动检查是否存在父模块。

    然后您可以像这样获取“根模块”:

    var rootModules = context.Modules.Where(x => x.ParentModuleId == null);
    

    如果你需要很多,你也可以创建一个扩展方法:

    public IQueryable<Module> WithoutParent(this IQueryable<Module> modules)
    {
        return modules.Where(x => x.ParentModuleId == null);
    }
    
    var rootModules = context.Modules.WithoutParent();
    

    【讨论】:

      【解决方案2】:

      无法添加评论,但 Kristof Claes 忘记添加评论了

      public List<Module> SubModules { get; set; }
      

      虚拟如:

      public virtual List<Module> SubModules { get; set; }
      

      否则 EntityFramework 在从数据库加载子项时无法为您预填充列表。所以正确的代码是:

      public class Module
      {
          public Module()
          {
              SubModules = new List<Module>();
          }
      
          // Other properties
      
          public int? ParentModuleId { get; set; }
      
          [ForeignKey("ParentModuleId")]
          public virtual List<Module> SubModules { get; set; }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-01
        • 2020-04-10
        • 2016-06-03
        • 1970-01-01
        • 1970-01-01
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多