Open RazvanB opened 4 years ago
@AndriySvyryd I am able to reproduce this on the latest daily build. Minimal code and model below. I'm not entirely sure what this does:
var builder = modelBuilder.Entity<Condition>()
.OwnsOne(x => x.LinkedCondition)
.HasOne(x => x.Condition)
.WithMany()
.HasForeignKey(x => x.ConditionId);
public static class Program
{
public static void Main()
{
using (var context = new SomeDbContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
}
}
}
public class LinkedCondition
{
public Guid? ConditionId { get; }
public Condition Condition { get; }
}
public class Condition
{
public Guid Id { get; set; }
public LinkedCondition LinkedCondition { get; }
}
public class SomeDbContext : DbContext
{
private static readonly ILoggerFactory
Logger = LoggerFactory.Create(x => x.AddConsole()); //.SetMinimumLevel(LogLevel.Debug));
public DbSet<Condition> Conditions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var builder = modelBuilder.Entity<Condition>()
.OwnsOne(x => x.LinkedCondition)
.HasOne(x => x.Condition)
.WithMany()
.HasForeignKey(x => x.ConditionId);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(Logger)
.EnableSensitiveDataLogging()
.UseSqlServer(Your.SqlServerConnectionString);
}
Model:
EntityType: Condition
Properties:
Id (Guid) Required PK AfterSave:Throw ValueGenerated.OnAdd
Keys:
Id PK
EntityType: LinkedCondition
Properties:
ConditionId (Nullable<Guid>) Required PK FK AfterSave:Throw
Id (no field, int) Shadow Required PK AfterSave:Throw ValueGenerated.OnAdd
Navigations:
Condition (Condition) ToPrincipal Condition
Keys:
ConditionId, Id PK
Foreign keys:
LinkedCondition {'ConditionId'} -> Condition {'Id'} Ownership ToPrincipal: Condition Cascade
My observations,
To explain further what I want to obtain with this example.
What I want to obtain is that I have, in terms of DDD, a value object LinkedCondition which contain another Condition Id.
And I want to add a FK to the same table for it.
The PK ConditionId is converted to a primitive wrapper to become also a value object.
@RazvanB I don't think EF Core can currently support the model you want to build, and I'm not entirely sure what it means in DDD to have a value object with a navigation property. At least for the moment, we're putting this on the backlog to throw a better exception when this kind of mapping is attempted.
TestFKSameTable.zip When trying to add a migration for attached example project, I'll get the following.
Steps to reproduce
I made the following structure as an example of what I want to accomplish.
And this is my DbContext configuration
I have done some debugging and I found that the Null Reference Exception happens at line
var ownerNavigation = ownership?.PrincipalToDependent.Name;
from methodThis is because
PrincipalToDependent
is null.If I replace that line with the following code the migration is completed because the navigation is found in
DependentToPrincipal
propertyFurther technical details
EF Core version: 3.1 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET Core 3.1 Operating system: Windows 10 v1909 IDE: Visual Studio 2019 16.5.4