使用单个dbcontext时在异常后恢复

时间:2013-04-28 23:50:27

标签: wpf entity-framework entity-framework-5 dbcontext

我正在使用实体框架将数据保存在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;
        }
    }

2 个答案:

答案 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层场景中,延迟加载并不合适。您可能应该为视图使用预先加载的所需数据,或者使用单独的方法调用来获取相关数据。