ef核心一对多关系抛出异常无法添加或更新子行

pgx2nnw8  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(527)

我的店和产品实体有一对多的关系,请看我的型号

public class Product
{
   public int ID { get; set; }
   public string Name { get; set; }
   public string Tag { get; set; }
   public string Brand { get; set; }
   public string Place { get; set; }

   public int ShopID { get; set; }
   public Shop Shop { get; set; }
}

public class Shop
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
    public string Number { get; set; }

    public ICollection<Product> Products { get; set; }
}

 public class ShopContext : DbContext
    {
        public ShopContext(DbContextOptions<ShopContext> options) : base(options)
        {
        }

        public DbSet<Shop> Shops { get; set; }
        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Shop>().ToTable("shop");
            modelBuilder.Entity<Product>().ToTable("product");
        }

    }

public class CreateModel : PageModel
{
    private readonly ShopContext _context;

    public CreateModel(ShopContext context)
    {
        _context = context;
    }

    public IActionResult OnGet()
    {
        ViewData["Shop"] = new SelectList(_context.Shops, "ID", "Name");

        return Page();
    }

    [BindProperty]
    public Product Product { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Products.Add(Product);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

创建页面中的商店是一个下拉列表,当我将新产品发布到处理程序时,我可以看到product.shopid是存在于shop表中的一个id,product.shop.id与product.shopid相同。但是当我调用savechangesasync()时,它抛出了一个异常:
mysqlexception:无法添加或更新子行:外键约束失败( shopdb . product ,约束 FK_product_shop_ShopID 外键( ShopID )参考文献 shop ( ID )删除时(级联)
在调用savechangesasync方法之前,我尝试将product.shop设置为null,但仍然无法工作,有人可以帮助吗?
asp.net core 2.0 razor pages应用程序,nuget:pomelo.entityframeworkcore.mysql v2.0.1

njthzxwz

njthzxwz1#

你不应该让 ShopID 如果设计需要可以为空。
你遇到的问题是因为 Add 方法还递归地将所有可通过导航属性访问且当前未被上下文跟踪的实体示例标记为 Added (即新的)。
可以通过多种方式解决:
将实体条目设置为 Added 而不是 Add 方法:

_context.Entry(Product).State = EntityState.Added;
await _context.SaveChangesAsync();

将导航属性设置为 null 打电话之前 Add :

Product.Shop = null;
_context.Products.Add(Product);
await _context.SaveChangesAsync();

在调用之前附加导航属性对象 Add :

if (Product.Shop != null) _context.Attach(Product.Shop);
_context.Products.Add(Product);
await _context.SaveChangesAsync();

使用 Update 而不是 Add :

_context.Products.Update(Product);
await _context.SaveChangesAsync();

最后一种技术在“保存数据-断开连接的实体-新实体和现有实体的混合”中进行了说明:
使用自动生成的键,update可以再次用于插入和更新,即使图形包含需要插入的实体和需要更新的实体的混合
因为它只在所有实体都使用自动生成的pks时才起作用,而且还会对相关实体产生不必要的更新,所以我不建议使用它。

x6yk4ghg

x6yk4ghg2#

声明 ShopIDProduct table,你在做什么 product.Shop = null; ,所以它尝试插入 ShopID 价值 null 在本专栏中。自从你的专栏 ShopIDProduct 表不可为空,这就是它的给定错误的原因。因为没有 IdShop 可为空的表。所以它的外键约束失败了。所以你要做的就是使用可为空的外键 public int? ShopID .

相关问题