【问题标题】:Entity Framework add object to new many to many Table Relation Error实体框架将对象添加到新的多对多表关系错误
【发布时间】:2021-08-25 14:41:36
【问题描述】:

我在“Items”和“Itemattributes”表之间的数据库上创建了一个新的多对多关系。

型号:

Item.cs

public class Item
{
    [Key]
    public int ItemCode { get; set; }
    public string ItemName { get; set; }
    public ICollection<ItemAttribute> ItemAttributes { get; set; }
}

ItemAttribute.cs

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

数据上下文

public DbSet<Item> Items { get; set; }
public DbSet<ItemAttribute> ItemAttributes { get; set; }

在包管理器控制台中使用命令:

Add-Migration FunnyNameForMigration
Update-Database 

实体框架创建一个表来连接“Items”和“ItemAttributes”表,“ItemsItemAttributes”。 当我尝试使用 ItemController 创建具有 2 个 ItemAttributes 的新项目时:

[HttpPost]
    public async Task<IActionResult> Post([Bind("ItemCode")] Item item)
    {
        _context.Items.Add(item);
        await _context.SaveChangesAsync();
        return Ok(item.ItemCode);
    }

我得到错误:

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'ItemAttributes' when IDENTITY_INSERT is set to OFF.

我猜到 Item / Itemattribute 关系只在新的“ItemsItemAttributes”表上,为什么 Entity Framework 试图在“Itemattribute”表上添加一些东西?以及如何使用 ItemAttributes 添加新项目?

更新

当我在表“ItemItemattribute”中手动插入表“Item”和“Itemattribute”之间的新连接时,它工作正常。我怀疑实体框架的自动插入有问题。

掘金:

【问题讨论】:

  • 请公开 Item 和 ItemAttribute 的所有类以及您发送到 Post 操作的内容
  • 您是否在 Db 上下文的 OnModelCreating 方法中添加了多对多关系?另外,正如 Nicola 所说,请向我们展示您的模型和 DbContext 的完整代码以及您如何发布项目。
  • @NicolaBiada 我添加了类中缺少的部分,我只向控制器发送了一个我创建的新项目对象
  • @MajdOdeh 我没有对 OnModelCreating 方法做任何事情

标签: c# entity-framework asp.net-core blazor


【解决方案1】:

您必须为 Items 和 ItemAttributes 中的 PK 字段打开 Identity:

[DatabaseGeneratedOption.Identity]
public int ItemId {get;set;}

[DatabaseGeneratedOption.Identity]
public int ItemAttributesId {get;set;}

【讨论】:

  • 我使用了[Key] DataAnnotation。这会干扰您的解决方案吗?
【解决方案2】:

我认为您在 POST 请求的正文中发送了 ItemCodeItemAttributeCode 字段。

您不能这样做,因为这些字段是自动递增的,并且默认情况下是受管理的。
尝试在没有它们的情况下发送模型。

【讨论】:

  • 不,我可以将新项目添加到表中,当我尝试将 ItemAttributes 添加到项目时引发错误
  • 同样的概念,检查ItemAttributeCode
  • 但是我添加了一个新项目而不是一个新属性。新项目有一个集合 (ICollection ItemAttributes)。但我所期望的是实体框架刚刚在“ItemsItemAttributes”表中添加了一个新条目,它显示了项目和属性之间的链接。我在这里想念什么?我觉得我不明白。
  • 您说:“当我尝试使用 ItemController 创建具有 2 个 ItemAttributes 的新项目时”,因此您添加了一个具有 两个 ItemAttributes 的项目。你如何创建这个模型?你能分享你的代码吗?
  • 实体框架应该自动检测任意数量的 ItemAttribute 对象并将它们添加到它应该创建的通信表中。问题不在于模型。问题太简单了,Entity Framework没有自动写入通讯表“ItemItemAttribute”。
【解决方案3】:

当 IDENTITY_INSERT 设置为 OFF 时,无法为表“ItemAttributes”中的标识列插入显式值。

错误表示当您使用ItemAttributes 创建新的Item 时,不要发布ItemAttributeCode 特定值。

只需像下面这样发布数据(以 Postman 为例):

另外,如果你使用[Bind("ItemCode")],它只会将ItemCode属性数据绑定到Item,并且该属性绑定来自表单的数据。

结果展示:

环境:

我使用 Ef Core 5.0.6 版

【讨论】:

  • 很明显,ItemAttributeCode 是 Key 并且有充分的理由自动生成。
  • 就是这样。那么您现在解决问题了吗?
  • 不,我仍然有自动插入到“Item”和“ItemaAttribute”之间的通信表“ItemItemaAttribute”的问题。错误只是一个提示,一个症状。
  • 有什么问题?我可以成功插入Item,ItemAttributeItemItemAttribute
  • 在我的问题中,当我添加一个带有 itemattributes 的新项目时,ItemAttributes 应该通过实体框架插入到通信表“ItemsItemAttributes”中。但相反,我得到了错误方向的错误。
【解决方案4】:

我的问题没有解决方案。无论如何,因为通信表正在工作,我手动更新表。不好的解决方法。

[HttpPut]
    public async Task<IActionResult> Put(Item item)
    {
        if (item.ItemAttributes != null)
        {
            string delete_sql = $"DELETE FROM ItemItemAttribute WHERE ItemsItemCode = '{item.ItemCode}'";
            _context.Database.ExecuteSqlRaw(delete_sql);
            
            foreach (ItemAttribute itemAttribute in item.ItemAttributes)
            {
                    string create_sql = $"INSERT INTO ItemItemAttribute (ItemAttributesItemAttributeCode, ItemsItemCode) VALUES ('{itemAttribute.ItemAttributeCode}', '{item.ItemCode}')";
                    _context.Database.ExecuteSqlRaw(create_sql);
            }
            item.ItemAttributes.Clear();
        }
        _context.Entry(item).State = EntityState.Modified;
        await _context.SaveChangesAsync();
        return NoContent();
    }

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多