简体   繁体   中英

EF code first - configure One-to-Zero-or-One relationship without shared PK/FK

I am trying to establish a One-to-Zero-or-One relationship between two entities and I want the dependent entity to still contain its own Indentity column, instead of it being a shared key.

I want to do as much as possible following the conventions and not declaring explicitly anything that does not require explicit declaration (so, no unnecessary data annotations or fluent api clauses)

The entites:

public class File
{
    public int FileId {get;set;}
    //some omitted file properties
    public virtual Task Task {get;set;}
}

public class Task
{
    public int TaskId {get;set;}
    //some omitted task properties
    public int FileId {get;set;}
    public virtual File File  {get;set;}
}

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<File>().HasOptional(f => f.Task).WithRequired(t => t.File);
            base.OnModelCreating(modelBuilder);
        }

This creates a weird relation where the TaskId is both PK and FK column of the Tasks table. Which, I think means that it should have the same value as the file ID? (That is a question:) )

So, how do I make TaskId hold its own, sequential value and have FileId become a foreign key to the Files table?

Or maybe in case of 1-0..1 I should rather get rid of the TaskId property and make FileId the PK/FK property?

Cheers!

Bidirectional one-to-one relationship with explicit FK property is not supported.

So either continue using what you have now - Shared Primary Key association . Just get rid of one of the TaskId or FileId properties from Task and make the remaining a PK (EF will automatically use it as FK because that's the default EF one-to-one relationship model).

Or get rid of the FieldId property from Task and use the following fluent configuration (all is necessary):

modelBuilder.Entity<File>()
    .HasOptional(f => f.Task)
    .WithRequired(t => t.File)
    .Map(m => m.MapKey("FileId"))
    .WillCascadeOnDelete();

But I would recommend using the first approach (if there is no special reason of not doing it like existing database etc.) because it's better supported - the second includes some LEFT OUTER JOIN s in SQL queries as you can see from this post EF - WithOptional - Left Outer Join? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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