添加行时出现 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 的调试检查表明ProductCategoryId
和ProductId
的值是正确的:
我的错误在哪里?
编辑我将建议的[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[InverseProperty("FrontPageProduct")]
到ProductCategory
属性FrontPageProduct
和Product
属性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。 我尝试了你的两个建议;通过.Find
ing 设置Product
和ProductCategory
,并注释掉nav.props。模型上。在这两种情况下,我都会遇到此异常:SqlException:INSERT 语句与 FOREIGN KEY 约束“FK_FrontPageProducts_Products_ProductId”冲突。冲突发生在数据库“MyStore”、表“dbo.Products”、列“Id”中。
你确定你的外键关系是正确的吗?您确定您从客户端获得了正确的 ProductId 和 ProductCategoryId 值,请检查它们。
我检查了ProductId
和ProductCategoryId
的值,它们是正确的。我在我的帖子中添加了另一个编辑,编辑 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