使用 EF4 Code First 的 Repository.Update 策略?
我正在使用 Entity Framework Code First 开发一个 MVC 站点,使用 Ninject 对控制器进行 DI,并且遇到了一个设计问题。我见过两种用于 Code First 更新的方法。第一个方法使用“通过 id 获取”,更改返回的对象的值,然后调用 Context.SaveChanges(),如下所示:
Controller:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
//Create a vm to hold the data from the form.
var sectionVm = new SectionEditViewModel();
//Copy the data from the http header to the object.
UpdateModel(sectionVm);
//Get the object from the database.
//_sectionRepository is injected in to the constructor.
var section = _sectionRepository.GetById(sectionVm.SectionId);
//Map from the view model to the actual model.
var viewSection = Mapper.Map(sectionVm, section);
_sectionRepository.Update();
return RedirectToAction("Index");
}
Repository:
public void Update()
{
_context.SaveChanges();
}
第二个方法创建模型对象,并将其附加到上下文,更改对象的状态,然后调用 SaveChanges()
。这里用作为消费者的测试方法来说明: 测试:
[TestMethod]
public void CanUpdateSection()
{
var repo = new SectionRepository();
var testSection = GetMockSection();
testSection.SomeProperty = "A new value";
testContact.AnotherProperty = "Another new value";
repo.Update(testSection);
var persistedUpdatedSection = repo.GetById(testSection.Id);
Assert.IsNotNull(persistedUpdatedSection);
CompareSections(testSection, persistedUpdatedSection);
}
存储库:
public void Update(Section entity)
{
using(var context = new SectionContext())
{
context.Sections.Attach(entity);
context.Entry(entity).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
}
哪种方式更好,或者还有其他更好的方式吗?
I'm working on an MVC site with Entity Framework Code First, using Ninject for DI to the controllers, and I've run into a design question. I've seen two methods used for updates with Code First. The first uses a "get by id," changes the values of the object returned, then calls Context.SaveChanges()
, like this:
Controller:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
//Create a vm to hold the data from the form.
var sectionVm = new SectionEditViewModel();
//Copy the data from the http header to the object.
UpdateModel(sectionVm);
//Get the object from the database.
//_sectionRepository is injected in to the constructor.
var section = _sectionRepository.GetById(sectionVm.SectionId);
//Map from the view model to the actual model.
var viewSection = Mapper.Map(sectionVm, section);
_sectionRepository.Update();
return RedirectToAction("Index");
}
Repository:
public void Update()
{
_context.SaveChanges();
}
The second method creates the model object, attaches it to the context, changes the state of the object, then calls SaveChanges()
. Illustrated here with a test method as the consumer:
Test:
[TestMethod]
public void CanUpdateSection()
{
var repo = new SectionRepository();
var testSection = GetMockSection();
testSection.SomeProperty = "A new value";
testContact.AnotherProperty = "Another new value";
repo.Update(testSection);
var persistedUpdatedSection = repo.GetById(testSection.Id);
Assert.IsNotNull(persistedUpdatedSection);
CompareSections(testSection, persistedUpdatedSection);
}
Repository:
public void Update(Section entity)
{
using(var context = new SectionContext())
{
context.Sections.Attach(entity);
context.Entry(entity).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
}
Which way is preferable, or is there another, better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一种方法更好。如果将 SaveChanges() 方法保留在其自己的存储库方法中,则可以进行多次编辑,然后尝试使用 Update() 一次提交所有编辑。如果一项编辑出现问题,则调用 Update() 时所有更改都将回滚。
The first way is better. If you keep the SaveChanges() method in it's own Repository method, you can make many edits and then attempt to commit them all at once using Update(). If there is an issue with one edit, all your changes will be rolled back when Update() is called.