Del*_*Boy 7 c# asp.net-mvc entity-framework
我知道它之前已被问过,但经过长时间的搜索和编码后,我无法采用干净利落的方法.这是我有的:
public class QuestionModel
{
public int QuestionID { get; set; }
public string QuestionText { get; set; }
public IList<QuestionChoiceModel> Choices { get; set; }
}
public class QuestionChoiceModel
{
public int ChoiceID { get; set; }
public string ChoiceText { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我在这个ASP.Net MVC应用程序中使用EF 5.Ninject使用的通用存储库模式和依赖注入InRequestScope()
已经到位并且工作顺利.这些模型映射到实体/从实体映射没有问题.
向数据库添加新问题很简单.我设置了一些QuestionChoice实例的Question属性,EF处理其余的.
问题是关于更新.假设我们在3个QuestionChoices的数据库中有一个问题:
ChoiceID QuestionID ChoiceText
-------- ---------- ----------
1 1 blah blah
2 1 blah blah
3 1 blah blah
Run Code Online (Sandbox Code Playgroud)
当打开问题的编辑页面(GET:/ Questions/Edit/1)时,我使用foreach
Razor 显示这3个选项.我已经写了一些JQuery代码,如果用户愿意,可以为输入元素添加或删除所需的标记.所以,用ID = 1的QuestionChoice可能在客户端进行编辑,ID = 2可能会被删除,并且新的ID = 4可能会增加.当用户按下Save按钮(POST:/ Questions/Edit/1)时,表单数据将完美地绑定到QuestionModel.模型正确映射到Question实体.这就是故事开始的地方!
现在的问题实体有QuestionChoices其中一些已经在数据库的集合,一些应该被添加到数据库中,有的应从数据库中删除.
我读了许多帖子: Entity Framework没有保存修改过的孩子
我可以用那种肮脏的方式处理编辑.还有新记录:
this._context.Entry(choice).State = EntityState.Added;
Run Code Online (Sandbox Code Playgroud)
但我正在寻找一种更优雅的方式.并处理应删除的记录.在这种情况下使用EF处理子实体的完整插入/更新/删除是否有一种好的方法?老实说,我对EF的期望更高.
小智 7
这是一个棘手的问题.不幸的是,我无法提供您喜欢的解决方案.我不相信这是可能的.EF无法跟踪对您的实体所做的更改,除非它们是在检索实体的上下文中进行的 - 这在Web环境中是不可能的.唯一可行的方法是在POST到/ Questions/Edit/1之后检索Question对象(在上下文中),并在POSTed Question和从中检索的问题之间执行一种"合并".数据库.这将包括使用POSTed为您QuestionModel
和QuestionChoiceModel
从数据库检索的每个属性分配属性QuestionModel
.我会说这也不是很好的做法,因为你会忘记包含一个属性.它会发生.
我能提供的最好(也是最简单)的解决方案是添加/编辑你的QuestionModel
并QuestionChoiceModel(s)
使用.Entry()
上面的方法.您将在此处牺牲"最佳实践",以获得不易出错的解决方案.
QuestionModel questionFromDb;
QuestionModel questionFromPost;
QuestionModelChoice[] deletedChoices = questionFromDb.Choices.Where(c => !questionFromPost.Choices.Any(c2 => c2.Id == c.Id));
using (var db = new DbContext())
{
db.Entry(questionFromPost).State = questionFromPost.Id == 0 ? EntityState.Added : EntityState.Modified;
foreach(var choice in questionFromPost.Choices)
{
db.Entry(choice).State = choice.Id == 0 ? EntityState.Added : EntityState.Modified;
}
foreach(var deletedChoice in deletedChoices)
{
db.Entry(deletedChoice).State = EntityState.Deleted;
}
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8158 次 |
最近记录: |