oknsyl
oknsyl

Reputation: 77

EF Core - Unable to determine the relationship represented by navigation (One-to-Many)

I am trying to create a simple One-to-many relationship but Ef Core somehow does not recognize it. I am still a beginner in this but I think I did this by the book (defined the relationship fully) so I don't get why EF Core is throwing this error:

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

Those are my two models: Asset.cs

public class Asset
{
    public int AssetId { get; set; }
    public string AssetName { get; set; }

    [ForeignKey("AssetTypeId")]
    public int AssetTypeId { get; set; }
    public AssetType AssetType { get; set; }
    
    public ICollection<AssetValue> AssetTypeValues { get; set; }
    
    public string Brand { get; set; }
    public string Model { get; set; }
    public string SerialNumber { get; set; }
    public string ProductNumber { get; set; }
    public DateTime PurchaseDate { get; set; }
    public decimal PurchasePrice { get; set; }
    
    [ForeignKey("LocationId")]
    public int? LocationId { get; set; }
    public Location Location { get; set; }

    [ForeignKey("InsuranceId")]
    public int InsuranceId { get; set; }
    public Insurance Insurance { get; set; }

    [ForeignKey("OwnerId")]
    public string? OwnerId { get; set; }
    public AppUser Owner { get; set; }

    [ForeignKey("InvoiceId")]
    public int? InvoiceId { get; set; }
    public Insurance Invoice { get; set; }

    public string? ImagePath { get; set; }
    public string? Description { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
}

Insurance.cs

public class Insurance
{
    public int InsuranceId { get; set; }

    [ForeignKey("InsuranceTypeId")]
    public int InsuranceTypeId { get; set; }
    public InsuranceType InsuranceType { get; set; }

    public string Insurer { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string? FilePath { get; set; }
    public string? Description { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }

    public ICollection<Asset> Assets { get; set; }
}

Also, if I remove this relationship, just for testing, migration still doesn't work and throwing errors about the other foreign keys in the Asset model. Is it because I have too many foreign keys so I have to define them in OnModelCreating?

Edit: ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<AppUser>
{
    public DbSet<Asset> Assets { get; set; }
    public DbSet<AssetType> AssetTypes { get; set; }
    public DbSet<AssetProp> AssetProps { get; set; }
    public DbSet<AssetValue> AssetValues { get; set; }
    public DbSet<Location> Locations { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<CompanyContact> CompanyContacts { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<InsuranceType> InsuranceTypes { get; set; }
    public DbSet<Insurance> Insurances { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Upvotes: 3

Views: 12941

Answers (1)

Richard Deeming
Richard Deeming

Reputation: 31198

If you specify the [ForeignKey] attribute, you need to do one of two things:

  • Add the attribute to the scalar property, and use the name of the navigation property; or
  • Add the attribute to the navigation property, and use the name of the scalar property.

So either:

[ForeignKey("Insurance")]
public int InsuranceId { get; set; }
public Insurance Insurance { get; set; }

or:

public int InsuranceId { get; set; }
[ForeignKey("InsuranceId")]
public Insurance Insurance { get; set; }

By putting the attribute on the scalar property and specifying the name of the scalar property, EF can't understand what you're trying to do.

This applies to all of your [ForeignKey("...")] attributes in the code.

NB: Since there is only one navigation property to each given entity type, and the scalar property names match the navigation property names with the Id suffix added, the [ForeignKey] attributes aren't actually required.


EDIT:

You have two navigation properties for the Insurance entity:

public Insurance Insurance { get; set; }
...
public Insurance Invoice { get; set; }

I suspect the second one should be:

public Invoice Invoice { get; set; }

Upvotes: 5

Related Questions