添加行

时间:2018-02-07 19:36:09

标签: c# linq asp.net-core entity-framework-core code-first

我正在尝试在表格中添加记录,但它无效。错误消息告诉我,我无法在ProductCategories的标识列中插入显式值,但我不知道我正在这样做。也许有些东西我没有得到实体导航,或者我的模型在某种程度上没有正确链接?

  

SqlException:当IDENTITY_INSERT设置为OFF时,无法在表'ProductCategories'中为identity列插入显式值。   当IDENTITY_INSERT设置为OFF时,无法在表'Products'中为identity列插入显式值。   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 - 对象的调试检查显示ProductCategoryIdProductId的值正确无误:

Debug-info

我/我的错误在哪里?

编辑我向所有模型添加了建议的[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)],但我仍然遇到同样的错误。

我认为始终将Id字段设置为EF中的默认主键。

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

编辑3 我将[ForeignKey("ProductId")][ForeignKey("ProductCategoryId")]添加到FrontPageProduct模型,但仍然获得相同的SqlException。

编辑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

2 个答案:

答案 0 :(得分:1)

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

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; }
}

答案 1 :(得分:1)

看起来您不需要为&#34; int Id&#34;设置DatabaseGenerated属性。字段,它是一种约定,并假设它是标识列。 顺便说一句,你确定你得到了同样的错误吗? 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; }
    }

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