One-to-one relationship with EFCore 2.1

c# entity-framework-core

Question

The following code was working with EFCore 2.0.

Since the 2.1 update, I get a blocking bug:

The child/dependent side could not be determined for the one-to-one relationship 
between 'Entity2.Main' and 'Entity1.Metadata'. 
To identify the child/dependent side of the relationship, configure the foreign key property. 
If these navigations should not be part of the same relationship configure them without specifying 
the inverse. See http://go.microsoft.com/fwlink/?LinkId=724062 for more details.

The tables are something like (they share the same id, but on different tables):

Table_Entity1:
- Id
- Name
- Description

Table_Entity2:
- Id
- Flag1
- Flag2

Entities are like:

public class Entity1
{
    public long Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public Entity2 Metadata {get;set;}
}

public class Entity2
{
    public long Id {get;set;}
    public bool Flag1 {get;set;}
    public bool Flag2 {get;set;}
    public Entity1 Main {get;set;}
}

They are declared as follow:

builder.Entity<Entity1>(b =>
{
    b.HasKey(e => e.Id);
    b.Property(e => e.Id).ValueGeneratedNever();
    b.HasOne<Entity2>(e => e.Metadata)
        .WithOne(e => e.Main)
        .HasForeignKey<Entity2>(e => e.Id)
        .HasPrincipalKey<Entity1>(e=>e.Id); 
    b.ToTable("Table_Entity1");
});

builder.Entity<Entity2>(b =>
{
     b.HasKey(e => e.Id);
     b.ToTable("Table_Entity2");
});

How can I solve this? I have tried all HasOne, WithOne, HasForeignKey combinations, nothing seem to work...

1
0
6/19/2018 7:37:11 AM

Accepted Answer

I have solved it by adding OwnsOne:

builder.Entity<Entity1>(b =>
{
    b.HasKey(e => e.Id);
    b.Property(e => e.Id).ValueGeneratedNever();
    b.OwnsOne<Entity2>(e => e.Metadata);
    b.HasOne<Entity2>(e => e.Metadata)
        .WithOne(e => e.Main)
        .HasForeignKey<Entity2>(e => e.Id);
    b.ToTable("Table_Entity1");
});

builder.Entity<Entity2>(b =>
{
     b.HasKey(e => e.Id);
     b.ToTable("Table_Entity2");
});
1
6/19/2018 7:36:39 AM

Popular Answer

By looking at your models, it seems to me Entity 1 owns Entity 2. Have you followed what's suggested in the Microsoft Document Owned Entity Types section: https://docs.microsoft.com/en-us/ef/core/modeling/owned-entities?

You can try to change the models to:

public class Entity2
{
    public bool Flag1 { get; set; }
    public bool Flag2 { get; set; }
}

public class Entity1
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public Entity2 Metadata { get; set; }
}

Then on the configurations:

builder.Entity<Entity1>(b =>
{
    b.HasKey(e1 => e1.Id);
    b.OwnsOne(e1 => e1.Metadata, md => {

        // I think the example on the Microsoft Doc is wrong but need to verify.
        // I opened an issue here: 
        //   https://github.com/aspnet/EntityFramework.Docs/issues/772

        md.ToTable("Table_Entity2");
    });

    b.ToTable("Table_Entity1");
});

Disclaim: I wrote anything by hand hence they're not tested.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow