在多对多关系中从表中实现读取和保存值的最佳方法是什么? 我想为选定的技术设置复选框或类似的东西。
我有表问题
public int Id { get; set; }
public string Name{ get; set; }
public Country Country { get; set; }
public int? CountryId { get; set; }
public ICollection<Technology> Technologies { get; set; }
表技术
public int Id { get; set; }
public string Name{ get; set; }
public ICollection<Question> Questions{ get; set; }
我使用属性创建了ViewModel QuestionViewModel - 不确定是否有必要
public int Id { get; set; }
public string Description { get; set; }
public IEnumerable<Technology> Technologies { get; set; } // not sure about this
保存无表技术。
也许我需要使用 ICollection Technologies 和 ICollection Questions 类来代替我当前的ViewModel?
Razor页面是没有Technology类的简单表单,也不确定如何实现。 实体框架从代码优先方法创建了表 TechnologyQuestions 。
保存操作如下所示
public ActionResult Save(Question question)
{
if (!ModelState.IsValid)
{
var viewModel = new QuestionViewModel
{
Countries = _context.Countries.ToList()
};
return View("NewForm", viewModel);
}
if (question.Id == 0)
_context.Questions.Add(question);
else
{
var questionInDb = _context.Questions.Single(q => q.Id == question.Id);
questionInDb.Name= question.Name;
questionInDb.CountryId = question.CountryId;
}
_context.SaveChanges();
return RedirectToAction("Index", "Home");
}
我正在使用C#MVC 5.感谢任何帮助或指导。
答案 0 :(得分:0)
当你添加表格技术时,你没有说出什么是无效的,所以我假设你的问题是EF在你将它们链接到问题时试图插入新技术。
您应该首先尝试将Technology对象附加到上下文:
if (question.Id == 0)
{
foreach(var tech in question.Technologies)
_context.Technologies.Attach(tech)
_context.Questions.Add(question);
}
else
{
var questionInDb = _context.Questions.Single(q => q.Id == question.Id);
questionInDb.Name= question.Name;
questionInDb.CountryId = question.CountryId;
foreach(var tech in question.Technologies.Where(t => !questionInDb.Technologies.Any(x => x.Id == t.Id)))
_context.Technologies.Attach(tech);
//Remove Technologies that have been unchecked in the page
//...
}
答案 1 :(得分:0)
我已经解决了这个问题。
QuestionViewModel 具有ICollection of Technology类。
在保存操作中,我有
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Question question, string[] techIds)
{
UpdatePostCategories(question, techIds);
....
_context.Questions.Add(question);
_context.SaveChanges();
}
UpdatePostCategories 方法如下所示
private void UpdatePostCategories(Question question, string[] techIds)
{
var selectedCategoriesHS = new HashSet<string>(techIds);
var postCategories = new HashSet<int>
(question.Technologies.Select(t=> t.Id));
foreach (var item in _context.Technologies)
{
if (selectedCategoriesHS.Contains(item.Id.ToString()))
{
if (!postCategories.Contains(item.Id))
{
question.Technologies.Add(item);
}
}
else
{
if (postCategories.Contains(item.Id))
{
question.Technologies.Remove(item);
}
}
}
}
在我的View复选框中,您可以选择所有技术,如下所示
<div class="form-group">
@foreach (var item in Model.Technologies)
{
<div>
<label>@Html.DisplayFor(model => item.Name)</label>
<input type="checkbox" value="@item.Id" name="techIds" />
</div>
}
</div>