问题
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:
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.
回答2:
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");
});
来源:https://stackoverflow.com/questions/50866633/one-to-one-relationship-with-efcore-2-1