Home > Net >  Many to Many relationship Entity Framework Core 5
Many to Many relationship Entity Framework Core 5

Time:10-01

I created a Blazor project and I have a many-to-many relationship between these classes:

public class ItemAttribute
{
    [Key]
    public int ItemAttributeCode { get; set; }
    public string Title { get; set; }
    public ICollection<Item> Items { get; set; }
    public ICollection<ItemAttributeCluster> itemAttributeClusters { get; set; }
}

and

public class ItemAttributeCluster
{
    [Key]
    public int ItemAttributeClusterCode { get; set; }
    public string Titel { get; set; }
    public bool IsMultiChoice { get; set; }
    public ICollection<ItemAttribute> itemAttributes { get; set; }
}

So far so good, EF generates the Join table ItemAttributeItemAttributeCluster, ok.

Then I try to add a new cluster of ItemAttributes for the first time with my controller:

// Create
[HttpPost]
public async Task<IActionResult> Post(ItemAttributeCluster itemAttributeCluster)
{
    _context.ItemAttributeClusters.Add(itemAttributeCluster);
    await _context.SaveChangesAsync();
    return Ok(itemAttributeCluster);
}

and I get this error:

Cannot insert explicit value for identity column in table 'ItemAttributes' when IDENTITY_INSERT is set to OFF.

What am I doing wrong?

CodePudding user response:

If this was an existing schema for the ItemAttribute / Cluster tables and their PK were defined as identity columns, you will need to tell EF to expect them using the [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] attribute alongside the Key designation.

When using a naming convention that EF recognizes like "ItemAttributeId" or "Id" I believe EF will default to assuming these are Identity columns, but with a name like "ItemAttributeCode" I believe it would assume a database generated option of "None" as default.

CodePudding user response:

try to add some navigation properties

public ItemAttributeCluster()
        {
            AttributeClusters = new HashSet<AttributeCluster>();
        }

        [Key]
        public int Id { get; set; }
        public string Titel { get; set; }
        public bool IsMultiChoice { get; set; }


        [InverseProperty(nameof(AttributeCluster.ItemAttributeClaster))]
        public virtual ICollection<AttributeCluster> AttributeClusters { get; set; }
    }


public partial class ItemAttribute
    {
        public ItemAttribute()
        {
            AttributeClusters = new HashSet<AttributeCluster>();
        }

        [Key]
        public int Id { get; set; }
        public string Title { get; set; }
        public virtual ICollection<Item> Items { get; set; }

        [InverseProperty(nameof(AttributeCluster.ItemAttribute))]
        public virtual ICollection<AttributeCluster> AttributeClusters { get; set; }
    }


public partial class AttributeCluster
    {
        [Key]
        public int Id { get; set; }
        public int ItemAttributeId { get; set; }
        public int ItemAttributeClasterId { get; set; }

        [ForeignKey(nameof(ItemAttributeId))]
        [InverseProperty("AttributeClusters")]
        public virtual ItemAttribute ItemAttribute { get; set; }
        [ForeignKey(nameof(ItemAttributeClasterId))]
        [InverseProperty(nameof(ItemAttributeCluster.AttributeClusters))]
        public virtual ItemAttributeCluster ItemAttributeClaster { get; set; 
    }

dbcontext (no any fluent apis at all)

 public virtual DbSet<AttributeCluster> AttributeClusters { get; set; }
 public virtual DbSet<ItemAttribute> ItemAttributes { get; set; }
 public virtual DbSet<ItemAttributeCluster> ItemAttributeClusters { get; set; }

Test

var itemAttributeClaster = new ItemAttributeCluster { Titel="titleClaster2", IsMultiChoice=false};

var itemAttribute = new ItemAttribute{Title="attrTitle" };

var attributeClaster = new AttributeCluster { ItemAttribute = itemAttribute, ItemAttributeClaster = itemAttributeClaster };

_context.AttributeClusters.Add(attributeClaster);
_context.SaveChanges();

it created 1 record in each of 3 tables

  • Related