简体   繁体   English

EF CodeFirst双向1:1或1关系

[英]EF CodeFirst bidirectional 1 : 0 or 1 relationship

I have 3 entities; 我有3个实体; Groups, Scopes, Vlans 组,范围,VLAN

What I'm trying to accomplish: 我要完成的工作:

  • A Group can have many Scopes 一个组可以有多个范围
  • A Group can have many Vlans 一组可以有多个VLAN
  • A Scope must have a Group 范围必须有一个组
  • A Vlan must have a Group 一个VLAN必须有一个Group
  • A Scope can have a Vlan 示波器可以有一个VLAN
  • A Vlan can have a Scope 一个VLAN可以有一个范围

So kind of a soft relationship between vlans and scopes. VLAN和范围之间存在某种软关系。

When not setting vlan or scope as a requirement EF complains about not knowing the principal of the relationship, So how do I fix this soft one to one relationship? 当不将VLAN或范围设置为要求时,EF抱怨不知道该关系的主体,那么如何解决这种一对一的软关系呢?

My Models: 我的模特:

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

There is a similar problem on SO, related to bidirectional Zero-to-One relationships: Implementing Zero Or One to Zero Or One relationship in EF Code first by Fluent API SO上存在类似的问题,与双向零对一关系有关: 首先通过Fluent API在EF代码中实现零或一对对零或一个关系

I've tried the same approach on your schema and it works. 我已经在您的架构上尝试了相同的方法,并且可以正常工作。 See my FluentAPI configuration below: 请参阅下面的我的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);

}

To be sure, that it suites your needs, see the generated SQL for VLANs and Scopes tables: 要确保它满足您的需求,请参见针对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);

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

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