实体框架代码第一树模型 [英] Entity Framework Code First Tree Model

查看:70
本文介绍了实体框架代码第一树模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

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

public int Id {get;组; }
public string标题{get;组; }
public string Action {get;组; }
public string Controller {get;组; }
public string Icon {get;组; }

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

哪些通过Code First初始化生成以下表格: p>

  CREATE TABLE [dbo]。[Modules](
[Id] [int] IDENTITY(1,1)NOT NULL ,
[Title] [nvarchar](max)NULL,
[Action] [nvarchar](max)NULL,
[Controller] [nvarchar](max)NULL,
[图标] [nvarchar](最大)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。模块_模块_Id] FOREIGN KEY([Module_Id])
参考[dbo]。[模块]([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 
---子模块
---子模块
子模块
子模块

我需要的是这两个孩子模块不能作为模块自己返回,但只能作为父母的孩子。



希望我已经解释了确定

解决方案

我将添加一个ParentModuleId属性( int?) public class Module
{
public Module()
{

 
SubModules = new List< Module>();
}

public int Id {get;组; }
public string标题{get;组; }
public string Action {get;组; }
public string Controller {get;组; }
public string Icon {get;组; }

public int? ParentModuleId {get;组; }

[ForeignKey(ParentModuleId)]
public virtual ICollection< Module> SubModules {get;组;注意,我还添加了一个 ForeignKey

$ b $ / code $ / code>属性到子模块列表,以确保使用新的ParentModuleId属性作为外键列。



这样,您可以手动检查存在的父模块。



然后您可以得到这样的根模块:

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

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

  public IQueryable< Module> WithoutParent(这个IQueryable&Module模块)
{
return modules.Where(x => x.ParentModuleId == null);
}

var rootModules = context.Modules.WithoutParent();


I have the following entity:

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; }
}

Which, when initialised through Code First generates the following table 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

The problem is that when I populate this table with a parent module (Module_Id of null) and two child modules (Module_Id of the parent Module) and query the DBContext's collection of Modules, I get the parent module with it's collection of child modules correctlly, but I also get the child modules returned by themselves.

So the Modules collection in the DbContext looks a bit like this:

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

What I need is for those two Child Modules to not be returned as Modules in their own right, but only as the children of the parent.

Hope I've explained this ok.

解决方案

I would add a ParentModuleId property (int?) to your Module class.

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; }
}

Notice how I have also added a ForeignKey attribute to the SubModules list to ensure that the new ParentModuleId property is used as the foreign key column.

This way you can manually check for the presence of a parent module.

You can then get the "root modules" like this:

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

If you need that a lot, you can also create an extension method:

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

var rootModules = context.Modules.WithoutParent();

这篇关于实体框架代码第一树模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆