Home > Enterprise >  Mapping a single navigation property in EF Core
Mapping a single navigation property in EF Core

Time:01-06

I am working on a project which involves EF Core.

I would like to use the foreign keys from Category with one single navigation property.

Therefore, Item stores the foreign keys of Category, and the names of the Category can be shown.

This is how the relationship looks like:

Relationship

Classes:

[Table("Item" , Schema = "public")]
public class Item
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ItemID {get; set;}
    public string Name {get; set;}
    public int CategoryID {get; set;}
    //Single Navigation Property
    public Category Category {get; set;}
}

[Table("Category" , Schema = "public")]
public class Category
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryID {get; set;}
    public string Name {get; set;}
}

DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Item>().ToTable("Item");
    modelBuilder.Entity<Category>().ToTable("Category");
    
    modelBuilder.Entity<Item>()
                .HasOne(i=>i.Category)
                .WithOne()
                .HasForeignKey<Item>(i=>i.CategoryID);
}

It shows an error

Duplicate key value violates unique constraint "IX_ItemDB_CategoryID"

Apparently, it means CategoryID cannot be duplicate in Item.

What am I doing wrong here? Thanks!

CodePudding user response:

actually your answer in this article. What you need to do is change the location of the navigation property. So Item should not have an Category property, Category should have a collection of Item for single navigation. the article describes other ways.

CodePudding user response:

In case I understand properly You need one to many relation and I can offer you that structure and if you use Migration your tables will be properly build in the database. No to do anything in the FluentApi to, Your FK, PK(identity) and Indexes will be automatically created

[Table("Item" , Schema = "public")]
public class Item
{
    public int Id {get; set;}
    public string Name {get; set;}

    public int CategoryId {get; set;}
    public Category Category {get; set;}
}

[Table("Category" , Schema = "public")]
public class Category
{
    public Category()
    {
       this.Items = new HashSet<Item>();
    }

    public int Id {get; set;}
    public string Name {get; set;}

    public virtual ICollection<Item> Items {get; set;}
}
  • Related