我正在使用实体框架将数据保存在N层Wpf应用程序中。我的dbcontext在所有存储库之间共享,永远不会丢弃。当我持久保存数据时,我将对象标记为已修改并尝试保存更改。如果在持久化对象时出现错误,则对象仍被标记为已修改,如果用户中止当前操作,则在保存另一个对象时将出现相同的错误。
我通过在dbcontext中覆盖SaveChanges解决了这个问题,如果有任何错误,我接受所有更改(请参阅下面的代码)。因此,如果错误扼杀了对象,并且所有对象都被标记为未更改,即使它们没有被持久化。
这感觉不对...... 有人同意这个解决方案吗? 另一个解决方案是在我的存储库中的每个方法中新建dbcontext并立即处理它们。这将使我的存储库更复杂和“noicy”,我也将失去延迟加载数据的能力...... 有没有人对我有不同的解决方案?
//In my repositories
public void UpdateObject(Object object)
{
dbContext.Entry(object).State = EntityState.Modified;
dbContext.SaveChanges();
}
//In my dbcontext class
private ObjectContext ObjectContext()
{
return (this as IObjectContextAdapter).ObjectContext;
}
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (Exception)
{
ObjectContext().AcceptAllChanges();
throw;
}
}
答案 0 :(得分:0)
我们的团队使用类似于以下的方法:
存储库:
public class StudentRepository
{
private readonly MyEntities _context;
public StudentRepository(MyEntities context)
{
_context = context;
}
// Basic CRUD methods etc
}
业务逻辑:
public AddStudent(Student student)
{
using( var context = new MyEntities())
{
var studentrepo = new StudentRepository(context);
studentrepo.Add(student);
context.SaveChanges();
}
}
这是一个过于简单的例子,但应该给你一个想法。为了减少代码,我们还为CRUD方法使用了基础通用存储库类。
如果我们正在处理的项目包含一个Web服务,我们在API控制器中实例化dbcontext并覆盖Dispose方法以摆脱它。
答案 1 :(得分:0)
拥有如此长寿的背景并不是一个好主意。在跟踪所有实体和更改时会变得越来越慢,可能会出现与并发相关的问题,并且您的上下文抛出的异常会影响整个应用程序。
http://msdn.microsoft.com/en-us/data/jj729737
另一个解决方案是在我的每个方法中新建dbcontext 立即重新存储和处理它们。这将使我的 存储库更复杂和“noicy”,我也将失去 延迟加载数据的能力
在断开连接的场景中,我会创建并处理每个请求/工作单元。关注你的回购变得复杂?然后不要使用这个额外的抽象层。回购真的有必要吗?你直接使用DbContext会有什么好处?
至于延迟加载,我认为在断开连接的n层场景中,延迟加载并不合适。您可能应该为视图使用预先加载的所需数据,或者使用单独的方法调用来获取相关数据。