EF Core unable to determine relationship represented by foreign keys in abstract class

c# ef-core-3.0 entity-framework-core

Question

I'm trying to implement an abstract class for CRUD objects which contains two references to the User class; one for the User which created the object and the other for the User which last modified it. Entity framework is unable to determine the relationship represented by the CreatedBy and ModifiedBy navigation properties on the class inheriting them (Department). A potential additional complication is that the User class also has a property of class Department, which is unrelated to the CreatedBy and ModifiedBy properties on Department.

Error message is below:

Unable to determine the relationship represented by navigation property 'Department.CreatedBy' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I'm using dotnet 3.0 and EF Core 3.0

I've attempted various configurations of the ForeignKey data attribute and using Fluent API following the EF documentation, but I was not able to get them to work.

public class User
{
    [Key]
    public int Id { get; set; }
    public Department Department { get; set; } = null!;
}

public class Department : AbstractCrudObject
{

}

public abstract class AbstractCrudObject
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("CreatedByUserId")]
    public User CreatedBy { get; set; } = null!;
    public int CreatedByUserId { get; set; }

    [ForeignKey("ModifiedByUserId")]
    public User ModifiedBy { get; set; } = null!;
    public int ModifiedByUserId { get; set; }
}


public class AppDbContext : DbContext
{
    public virtual DbSet<User> Users { get; set; } = null!;
    public virtual DbSet<Department> Departments { get; set; } = null!;
    public AppDbContext()
    {
    }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}
1
1
10/15/2019 12:05:02 PM

Accepted Answer

A potential additional complication is that the User class also has a property of class Department, which is unrelated to the CreatedBy and ModifiedBy properties on Department.

That's the problem - EF Core does not know whether they are unrelated, or it is related to one of them (and which one), so you have to configure that explicitly using the fluent API.

The bare minimum is to specify the multiplicity and navigation properties of the desired relationships - in this case, 3 many-to-one relationships with reference navigation property at the dependent ends and no collection navigation property at the principal ends:

modelBuilder.Entity<User>()
    .HasOne(e => e.Department)
    .WithMany();

modelBuilder.Entity<Department>()
    .HasOne(e => e.CreatedBy)
    .WithMany();

modelBuilder.Entity<Department>()
    .HasOne(e => e.ModifiedBy)
    .WithMany();
1
10/15/2019 12:04:30 PM


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