Reputation: 5008
I have 3 entities; Groups, Scopes, Vlans
What I'm trying to accomplish:
So kind of a soft relationship between vlans and scopes.
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?
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; }
}
Upvotes: 0
Views: 351
Reputation: 107
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
I've tried the same approach on your schema and it works. See my FluentAPI configuration below:
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:
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);
Upvotes: 1