EF CodeFirst双向1:0或1关系

时间:2016-06-02 11:30:15

标签: c# entity-framework ef-code-first

我有3个实体;小组,范围,Vlans

我正在努力实现的目标:

  • 一个群组可以拥有多个范围
  • 一个群体可以有很多Vlans
  • 范围必须有一个组
  • Vlan必须有一个组
  • 范围可以有Vlan
  • Vlan可以有一个范围

vlan和范围之间有一种柔和的关系。

当没有将vlan或范围设置为要求时,EF抱怨不知道关系的主体,那么如何修复这种软关系呢?

我的模特:

public class Group
{
    public Group()
    {
        Scopes = new HashSet<Scope>();
        Vlans = new HashSet<VLAN>();
    }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public ICollection<VLAN> Vlans { get; set; } 
    public ICollection<Scope> Scopes { get; set; } 
}
public class Scope
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }     
    public virtual VLAN Vlan { get; set; }
    public virtual Group Group { get; set; }
}
public class VLAN
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public virtual Scope Scope { get; set; }
    [Required]
    public virtual Group Group { get; set; }
}

1 个答案:

答案 0 :(得分:1)

SO上存在类似的问题,与双向零对一关系有关: Implementing Zero Or One to Zero Or One relationship in EF Code first by Fluent API

我在您的架构上尝试了相同的方法,但它确实有效。 请参阅下面的我的FluentAPI配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<VLAN>()
            .HasOptional(vlan => vlan.Scope)
            .WithOptionalPrincipal();

        modelBuilder.Entity<VLAN>()
            .HasRequired(vlan => vlan.Group);

        modelBuilder.Entity<Scope>()
            .HasOptional(scope => scope.Vlan)
            .WithOptionalPrincipal();

        modelBuilder.Entity<Scope>()
            .HasRequired(scope => scope.Group);

        modelBuilder.Entity<Group>()
            .HasMany(group => group.Scopes);
        modelBuilder.Entity<Group>()
            .HasMany(group => group.Vlans);

}

可以肯定的是,它满足您的需求,请参阅为VLAN和范围表生成的SQL:

CREATE TABLE [dbo].[Scopes] (
[Id]       INT            IDENTITY (1, 1) NOT NULL,
[VLAN_Id]  INT            NULL,
[Group_Id] INT            NOT NULL,
CONSTRAINT [PK_dbo.Scopes] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Scopes_dbo.VLANs_VLAN_Id] FOREIGN KEY ([VLAN_Id]) REFERENCES [dbo].[VLANs] ([Id]),
CONSTRAINT [FK_dbo.Scopes_dbo.Groups_Group_Id] FOREIGN KEY ([Group_Id]) REFERENCES [dbo].[Groups] ([Id]) ON DELETE CASCADE);

CREATE TABLE [dbo].[VLANs] (
[Id]       INT            IDENTITY (1, 1) NOT NULL,
[Scope_Id] INT            NULL,
[Group_Id] INT            NOT NULL,
CONSTRAINT [PK_dbo.VLANs] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.VLANs_dbo.Scopes_Scope_Id] FOREIGN KEY ([Scope_Id]) REFERENCES [dbo].[Scopes] ([Id]),
CONSTRAINT [FK_dbo.VLANs_dbo.Groups_Group_Id] FOREIGN KEY ([Group_Id]) REFERENCES [dbo].[Groups] ([Id]) ON DELETE CASCADE);