添加行时出现 DbUpdateException

Posted

技术标签:

【中文标题】添加行时出现 DbUpdateException【英文标题】:Getting DbUpdateException when adding a row 【发布时间】:2018-02-07 19:36:09 【问题描述】:

我正在尝试在表格中添加一条记录,但它不起作用。错误消息告诉我,我无法在 ProductCategories 的标识列中插入显式值,但我不知道我正在这样做。也许我对实体导航没有了解,或者我的模型没有正确链接?

SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“ProductCategories”中插入标识列的显式值。 当 IDENTITY_INSERT 设置为 OFF 时,无法在表“产品”中插入标识列的显式值。 System.Data.SqlClient.SqlCommand+c.b__108_0(任务结果)

DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch+d__32.MoveNext()

这是失败的代码(await _context.SaveChangesAsync();):

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> FrontPageProduct(ViewModelFrontPageProduct frontPageProduct)

    var fpp = new FrontPageProduct()
    
        ProductCategoryId = frontPageProduct.ProductCategoryId,
        ProductId = frontPageProduct.ProductId,
        SortOrder = 0
    ;
    _context.Add(fpp);
    await _context.SaveChangesAsync();
    return View("Index", new  id = fpp.ProductCategoryId, tab = 2 );

这些是涉及的实体模型:

public class Product

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id  get; set; 
    public string Title  get; set; 
    public string Info  get; set; 
    public decimal Price  get; set; 
    public List<FrontPageProduct> InFrontPages  get; set; 
    public List<ProductInCategory> InCategories  get; set; 


public class ProductCategory

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id  get; set; 
    public int SortOrder  get; set; 
    public string Title  get; set; 
    [ForeignKey(nameof(ParentCategory))]
    public int? ParentId  get; set; 
    public ProductCategory ParentCategory  get; set; 
    public ICollection<ProductCategory> Children  get; set;  = new List<ProductCategory>();
    public List<ProductInCategory> ProductInCategory  get; set; 


public class FrontPageProduct

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id  get; set; 
    public int ProductCategoryId  get; set; 
    public int ProductId  get; set; 
    public int SortOrder  get; set; 
    [ForeignKey("ProductId")]
    public virtual Product Product  get; set; 
    [ForeignKey("ProductCategoryId")]
    public virtual ProductCategory ProductCategory  get; set; 

fpp-object 的调试检查表明ProductCategoryIdProductId 的值是正确的:

我的错误在哪里?

编辑我将建议的[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)] 添加到所有模型中,但仍然出现相同的错误。

我认为无论如何,Id 字段始终设置为主键作为 EF 中的默认值。

编辑 2 我尝试在我的控制器方法中添加 [FromBody],但这只会导致空白屏幕、没有错误消息,并且没有对数据库进行任何更改。

EDIT 3 我在FrontPageProduct 模型中添加了[ForeignKey("ProductId")][ForeignKey("ProductCategoryId")],但仍然得到相同的SqlException。

EDIT 4这些是我的四个表的外键:

FrontPageProducts:

FK_FrontPageProducts_ProductCategories_ProductCategoryId

FK_FrontPageProducts_Products_ProductId

ProductCategories:

FK_ProductCategories_ProductCategories_ParentId

Products:

没有

ProductsInCategories:

FK_ProductsInCategories_FrontPageProducts_FrontPageProductId

FK_ProductsInCategories_ProductCategories_ProductCategoryId

FK_ProductsInCategories_Products_ProductId

【问题讨论】:

尝试向 FrontPageProduct 添加导航属性 该错误表明ProductCategory 不存在,它正在尝试创建它,但它无法设置FrontPageProduct.ProductCategoryId,因为您已明确设置它。你确定你的模型绑定工作正常吗?我注意到你没有使用[FromBody] @Brad 我试过[FromBody],但这对我没有任何好处。请参阅我的问题底部的编辑 2。 我刚刚意识到你也有像 public List InFrontPages get; 这样的集合的属性。放; ,请用 InversePropertyAttribute 标记它们。 @hazimdikenli 添加[InverseProperty("FrontPageProduct")]ProductCategory 属性FrontPageProductProduct 属性InFrontPages 在我尝试添加迁移时给我这个错误消息:属性'InFrontPages 上的InversePropertyAttribute ' 类型 'Product' 无效。属性“FrontPageProduct”不是相关类型“FrontPageProduct”的有效导航属性。确保该属性存在并且是有效的引用或集合导航属性。 【参考方案1】:

看起来您不需要为“int Id”字段设置 DatabaseGenerated 属性,这是一个约定,并假设它是 Identity Column。 顺便说一句,你确定你得到同样的错误吗? imgur 链接对我不起作用。您真的需要 FrontPage 类中的 Product 和 ProductCategory,如果您可以轻松地将它们注释掉并进行测试,请这样做,如果没有,您可以尝试为它们设置值,如下所示。

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> FrontPageProduct(ViewModelFrontPageProduct frontPageProduct)

    var fpp = new FrontPageProduct()
    
        ProductCategoryId = frontPageProduct.ProductCategoryId,
        ProductId = frontPageProduct.ProductId,
Product = _context.Set<Product>().Find(frontPageProduct.ProductId),
ProductCategory = _context.Set<ProductCategory>().Find(frontPageProduct.ProductCategoryId),
        SortOrder = 0
    ;
    _context.Add(fpp);
    await _context.SaveChangesAsync();
    return View("Index", new  id = fpp.ProductCategoryId, tab = 2 );

将 Key 和 DatabaseGenerated 属性应用于模型上的每个 Id 列,因此 EF 知道它是一个标识列,它需要取回生成的 id 值。

    public class Product
    
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id  get; set; 
        public string Title  get; set; 
        public string Info  get; set; 
        public decimal Price  get; set; 
[InverseProperty("Product")]
        public IEnumerable<FrontPageProduct> InFrontPages  get; set; 
        public List<ProductInCategory> InCategories  get; set; 
    

    public class ProductCategory
    
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id  get; set; 
        public int SortOrder  get; set; 
        public string Title  get; set; 
        [ForeignKey(nameof(ParentCategory))]
        public int? ParentId  get; set; 
        public ProductCategory ParentCategory  get; set; 
        public ICollection<ProductCategory> Children  get; set;  = new List<ProductCategory>();
        public List<ProductInCategory> ProductInCategory  get; set; 
    

    public class FrontPageProduct
    
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id  get; set; 
        public int ProductCategoryId  get; set; 
        public int ProductId  get; set; 
        public int SortOrder  get; set; 
    [ForeignKey("ProductId")]
        public virtual Product Product  get; set; 
    [ForeignKey("ProductCategoryId ")]
        public virtual ProductCategory ProductCategory  get; set; 
    

编辑:您应该添加导航属性,就像我在上面添加的一样。将它们设为虚拟也有助于延迟加载。

【讨论】:

进行更改后我仍然收到相同的错误。请参阅我的问题中的编辑 3。 我尝试了你的两个建议;通过.Finding 设置ProductProductCategory,并注释掉nav.props。模型上。在这两种情况下,我都会遇到此异常:SqlException:INSERT 语句与 FOREIGN KEY 约束“FK_FrontPageProducts_Products_ProductId”冲突。冲突发生在数据库“MyStore”、表“dbo.Products”、列“Id”中。 你确定你的外键关系是正确的吗?您确定您从客户端获得了正确的 ProductId 和 ProductCategoryId 值,请检查它们。 我检查了ProductIdProductCategoryId 的值,它们是正确的。我在我的帖子中添加了另一个编辑,编辑 4 - 你可以看到所有外键:FrontPageProducts 的 FK 是 ProductCategories_ProductCategoryId 和 Products_ProductId。 ProductCategories 的 FK:ProductCategories_ParentId。 Products 的 FK:无。 ProductsInCategories 的 FK:FrontPageProducts_FrontPageProductId、ProductCategories_ProductCategoryId 和 Products_ProductId。【参考方案2】:

Id 字段应该是数据库中的主键,因此您可以在实体模型中指定它。 - 添加[密钥]

public class Product

    [Key]
    public int Id  get; set; 
    public string Title  get; set; 
    public string Info  get; set; 
    public decimal Price  get; set; 
    public IEnumerable<FrontPageProduct> InFrontPages  get; set; 
    public List<ProductInCategory> InCategories  get; set; 

【讨论】:

您还应该告诉 EF ID 列是自动生成的。 [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] @hazimdikenli 我试过了,但没有任何区别。还是一样的错误。

以上是关于添加行时出现 DbUpdateException的主要内容,如果未能解决你的问题,请参考以下文章

DbUpdateException- 在我捕获所有异常时未处理重复的键错误

MVC EF - System.Data.Entity.Infrastructure.DbUpdateException

单击表格视图行时出现异常

在Android Studio终端中运行时出现IO异常[重复]

sql语句怎么添加一条记录?

如何在命令行登陆mysql数据库,添加一张表