我的商店和产品实体有一对多关系,请查看我的模型
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
,CONSTRAINT FK_product_shop_ShopID
FOREIGN KEY( ShopID
)REFERENCES shop
( ID
)ON DELETE CASCADE)
我尝试在调用saveChangesAsync方法之前将product.Shop设置为null,但仍然无法工作,任何人都可以提供帮助吗?
ASP.NET Core 2.0 Razor Pages应用程序,Nuget:Pomelo.EntityFrameworkCore.MySql v2.0.1
2 回答
在
Product
表中将ShopID
声明为可为空,您正在执行product.Shop = null;
,因此它会尝试在此列中插入ShopID
valuenull
. 由于Product
表中的ShopID
列不可为空,这就是它给出错误的原因 . 因为Shop
表中没有Id
可以为空 . 所以它给出 foreign key constraint fails 例外 . 所以你要做的就是使用像public int? ShopID
这样可以为空的外键 .如果设计要求,则不应使
ShopID
为空 .您遇到的问题是因为
Add
方法还递归地标记了所有可通过导航属性访问的实体实例,并且当前未被上下文跟踪为Added
(即new) .它可以通过多种方式解决:
Added
而不是Add
方法:null
before ,调用Add
:Add
:Update
而不是Add
:最后一种技术在_1380213中解释:
由于它仅在所有实体使用自动生成的PK时起作用,并且还产生相关实体的不必要更新,因此我不推荐它 .