Defining one side of a one to many relationship with PostgreSQL entity Framework

c# entity-framework-core postgresql

Question

I am, essentially, trying to define just one side of a one to many relationship using PostgreSQL entity framework and am producing the following error:

System.InvalidOperationException: 'Unable to determine the relationship represented by navigation property 'UserDao.TypeDao' of type 'TypeDao'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

So a little detail:

I am using asp.net core 3.1 using Razor Pages, Database is Postgres 12.2 and I am using Npgsql.EntityFrameworkCore.PostgreSQL 3.1.2

This is a conversion from an MVC project using EntityFramework 6.x using SQL Server

This is a large existing database so not using migrations but rather coding up the data access objects and context by hand.

I will talk about two data access classes UserDao and TypeDao

TypeDao is used throughout the database on hundreds of tables so what I want to achieve is that UserDao has one TypeDao and TypeDao "can be used in" many users. So I don't want a collection, in fact hundreds of collections, in the TypeDao object for UserDao, ProductDao, etc. etc.

So here are cut down versions of my UserDao and TypeDao data access objects:

[Table("user", Schema = "shared_kernal")]
public class UserDao
{
    [Key]
    [Column("id")]
    public Guid Id { get; set; }

    [Column("type_id")]
    public Guid? TypeId { get; set; }

    [ForeignKey("TypeId")]
    public TypeDao Type { get; set; }
}

[Table("type", Schema = "shared_kernal")]
public class TypeDao
{
    [Key]
    [Column("id")]
    public Guid Id { get; set; }

    [Column("creator_id")]
    public Guid CreatorId { get; set; }

    [ForeignKey("CreatorId")]
    public UserDao Creator { get; set; }
}

As you can see there is a relationship defined in Type back to the User as the creator, as new types can be added, but there is no relationship intended to be the other side of the relationship defined in User to Type

This feels like the possible root of the error as it might well be confusing to ef to infer that I don't wan't the Creator relationship to be the other side of the Type relationship in User.

So... How can this be done?

1
1
3/21/2020 2:39:11 AM

Accepted Answer

Such relationships require Manual configuration - a Has{One|Many} followed by With{One|Many} pair. These are used to identify the relationship ends, multiplicity and the associated navigation property (or no navigation property) of each end.

So the minimum needed to "unpair" UserDao.Type from TypeDao.Creator is

modelBuilder.Entity<UserDao>()
    .HasOne(e => e.Type) // reference navigation property
    .WithMany(); // no collection navigation property

or

modelBuilder.Entity<TypeDao>()
    .HasOne(e => e.Creator) // reference navigation property
    .WithMany(); // no collection navigation property

For more info, see Relationships - Manual Configuration - Single navigation property section of the EF Core documentation.

1
3/21/2020 2:45:12 AM


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