问题
I have three entities:
public class MainEntity()
{
public long Id { get; set; }
public long EntityAId { get; set; }
public EntityA OptionalEntityA { get; set; }
public long EntityBId { get; set; }
public EntityB OptionalEntityB { get; set; }
public string SProp { get; set; }
}
public class EntityA()
{
public long Id { get; set; }
public long MainEntityId { get; set; }
public MainEntity RequiredEntity { get; set; }
}
public class EntityB()
{
public long Id { get; set; }
public long MainEntityId { get; set; }
public MainEntity RequiredEntity { get; set; }
}
All three entities have there own Id generated by database:
Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
How can I define the Relationship between MainEntity and EntityA and EntityB in order to have:
- MainEntity may have zero or one EntityA
- MainEntity may have zero or one EntityB
- EntityA must have one MainEntity
- EntityB must have one MainEntity
In my MainEntityConfigurationMap I have defined relation like this:
HasOptional(m => m.OptionalEntityA).WithRequired(ea => ea.RequiredEntity);
HasOptional(m => m.OptionalEntityB).WithRequired(eb => eb.RequiredEntity);
Looking at the generated migration I have this for EntityA:
CreateTable(
"dbo.EntityA",
c => new
{
Id = c.Long(nullable: false, identity: true),
MainEntityId = c.Long(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.MainEntity", t => t.Id)
.Index(t => t.Id);
Entity Framework is defining a shared primary key here, is there a way to avoid that and make MainEntityId poiting to MainEntity.Id?
回答1:
Entity framework supports one-to-one relation only on top of shared primary key (PK in dependent table is also FK to principal table). The reason is that FK in dependent table must be unique to enforce one-to-one relation but EF currently doesn't support unique constraint (except PK).
回答2:
And to add on what @Ladislav Mrmka said...
Here is a full study on the various one-to-one modalities - and particularly how to make it using FK-s
instead of tying up PK-s (but don't raise your hopes up too high).
Create a Unique Constraint To Enforce the Relationship as a One to One
It boils down to executing a SQL manually (during Seed-ing or similar Db initialization) - which adds a UNIQUE CONSTRAINT
...
However, even in that case it won't work for you - or not w/o changes.
If I'm not mistaking - you'd have to give up one navigation property - and most likely the OptionEntityA/B
- as unique column cannot support NULL.
来源:https://stackoverflow.com/questions/16079747/one-to-zero-or-one-relationship-with-ef5-fluent-mapping