ASP MVC Entity Framework 核心。更新表单 post 上的多对多关系
ASP MVC Entity Framework core. Update many to many relationship on form post
我想知道在提交表单时更新多对多关系的好习惯。
我得到了这两个实体,并且我使用了 EF 核心 5 中的默认多对多关系:
public class BlogEntry
{
public int Id { get; set; }
[Required]
[MaxLength(200)]
public string Title { get; set; }
[Required]
public string EntryText { get; set; }
[NotMapped]
public IEnumerable<string> CategoriesToPublish { get; set; }
public ICollection<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<BlogEntry> BlogEntries { get; set; }
}
上下文:
public DbSet<BlogEntry> BlogEntries { get; set; }
public DbSet<Category> Categories { get; set; }
我有一个带有多选字段的表单来表示这种关系。见图像
form
我没有在表单上使用关系 属性(maube 我应该,但我不知道),我有另一个 属性 将关系转换为字符串列表调用 CategoriesToPublish
以便我可以加载多选并检索 post 上的选择。
在 post 操作方法上,我想迭代此 CategoriesToPublish
并更新所有关系。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Publish(BlogEntry blogEntry)
{
if (ModelState.IsValid)
{
blogEntry.Categories = await _context.Categories.Where(x => x.BlogEntries.Any(x => x.Id == blogEntry.Id)).ToListAsync();
await UpdateCategories(blogEntry);
_context.Update(blogEntry);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(List));
}
return View(blogEntry);
}
但是我面临的问题是 Categories
关系没有加载到 postback 上。如果我尝试手动加载它并保存上下文,我会收到一条错误消息 SqlException: Violation of PRIMARY KEY constraint 'PK_BlogEntryCategory'. Cannot insert duplicate key in object 'dbo.BlogEntryCategory'
我不确定如何解决这个问题。有什么建议吗?
经过大量搜索,我找到了解决方案。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Publish(BlogEntry blogEntry)
{
if (ModelState.IsValid)
{
blogEntry = _context.Update(blogEntry).Entity;
blogEntry.Categories = await _context.Entry(blogEntry).Collection(u => u.Categories).Query().ToListAsync();
await UpdateCategories(blogEntry);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(List));
}
return View(blogEntry);
}
我在 Update
:
之后检索了 blogEntry
blogEntry = _context.Update(blogEntry).Entity;
此时 Categories
仍然是空的,但现在我们可以再次从数据库加载它们:
blogEntry.Categories = await _context.Entry(blogEntry).Collection(u => u.Categories).Query().ToListAsync();
还有 boila,现在我们可以迭代所有类别,如果需要可以更改它们,它不会抱怨重复键。
我想知道在提交表单时更新多对多关系的好习惯。
我得到了这两个实体,并且我使用了 EF 核心 5 中的默认多对多关系:
public class BlogEntry
{
public int Id { get; set; }
[Required]
[MaxLength(200)]
public string Title { get; set; }
[Required]
public string EntryText { get; set; }
[NotMapped]
public IEnumerable<string> CategoriesToPublish { get; set; }
public ICollection<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<BlogEntry> BlogEntries { get; set; }
}
上下文:
public DbSet<BlogEntry> BlogEntries { get; set; }
public DbSet<Category> Categories { get; set; }
我有一个带有多选字段的表单来表示这种关系。见图像 form
我没有在表单上使用关系 属性(maube 我应该,但我不知道),我有另一个 属性 将关系转换为字符串列表调用 CategoriesToPublish
以便我可以加载多选并检索 post 上的选择。
在 post 操作方法上,我想迭代此 CategoriesToPublish
并更新所有关系。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Publish(BlogEntry blogEntry)
{
if (ModelState.IsValid)
{
blogEntry.Categories = await _context.Categories.Where(x => x.BlogEntries.Any(x => x.Id == blogEntry.Id)).ToListAsync();
await UpdateCategories(blogEntry);
_context.Update(blogEntry);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(List));
}
return View(blogEntry);
}
但是我面临的问题是 Categories
关系没有加载到 postback 上。如果我尝试手动加载它并保存上下文,我会收到一条错误消息 SqlException: Violation of PRIMARY KEY constraint 'PK_BlogEntryCategory'. Cannot insert duplicate key in object 'dbo.BlogEntryCategory'
我不确定如何解决这个问题。有什么建议吗?
经过大量搜索,我找到了解决方案。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Publish(BlogEntry blogEntry)
{
if (ModelState.IsValid)
{
blogEntry = _context.Update(blogEntry).Entity;
blogEntry.Categories = await _context.Entry(blogEntry).Collection(u => u.Categories).Query().ToListAsync();
await UpdateCategories(blogEntry);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(List));
}
return View(blogEntry);
}
我在 Update
:
blogEntry = _context.Update(blogEntry).Entity;
此时 Categories
仍然是空的,但现在我们可以再次从数据库加载它们:
blogEntry.Categories = await _context.Entry(blogEntry).Collection(u => u.Categories).Query().ToListAsync();
还有 boila,现在我们可以迭代所有类别,如果需要可以更改它们,它不会抱怨重复键。