Mohammad Akbari
Mohammad Akbari

Reputation: 4776

Entity Framework core one to one relationship generate one to many in SQL Server

For one-to-one relationship in Entity Framework core (rc1 or rc2) based on this tutorial http://ef.readthedocs.io/en/latest/modeling/relationships.html#one-to-one, I use this code:

public class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<BlogImage> BlogImages { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasOne(p => p.BlogImage)
            .WithOne(i => i.Blog)
            .HasForeignKey<BlogImage>(b => b.BlogForeignKey);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

    public int BlogForeignKey { get; set; }
    public Blog Blog { get; set; }
}

But after running the migration, and checking the database, I noticed that the generated tables have the following relationship:

enter image description here

What is solution?

Upvotes: 3

Views: 2135

Answers (2)

Morteza Manavi
Morteza Manavi

Reputation: 33216

Your code looks good, and you are in fact creating a 1:1 relationship between Blog and BlogImage objects and EF Core recognizes this by allowing you to have a bidirectional association between these two objects.

The only problem is that EF Core failed to translate this one to one association to the database by creating a unique constraint on BlogForeignKey column and as a result you have a one to one association in your object model which is mapped to a one to many relationship in your database.

This is a Bug in EF Core which will be fixed in the final release.

Now if you want to create a Shared Primary Key Association then the answer provided by @Gert is the way to go but if your intention was to create your one to one association on a unique foreign key (i.e. BlogForeignKey) or basically a One-to-One Foreign Key Association then don't change your code, just manually create a unique constraint on BlogForeignKey column and wait for the RTM version which is scheduled to come out by the end of this month.

Upvotes: 2

Gert Arnold
Gert Arnold

Reputation: 109165

BlogImageId should be BlogImage's primary key and the foreign key to Blog:

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }
    // Removed BlogForeignKey

    public Blog Blog { get; set; }
}

modelBuilder.Entity<Blog>()
    .HasOne(p => p.BlogImage)
    .WithOne(i => i.Blog)
    .HasForeignKey<BlogImage>(b => b.BlogImageId); // BlogImageId is FK

Upvotes: 1

Related Questions