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

Wpf 使用单个dbcontext时在异常后恢复,wpf,entity-framework,entity-framework-5,dbcontext,Wpf,Entity Framework,Entity Framework 5,Dbcontext,我正在使用实体框架在N层Wpf应用程序中持久化数据。My dbcontext在所有存储库中共享,永远不会被释放。当我保存数据时,我将对象标记为已修改,并尝试保存更改。如果在保存对象时出现错误,该对象仍被标记为已修改,并且如果用户中止当前操作,则在保存另一个对象时将收到相同的错误 我通过在dbcontext中重写SaveChanges解决了这个问题,如果出现任何错误,我接受所有更改(请参阅下面的代码)。因此,如果对象发生错误,并且所有对象都被标记为未更改,即使它们未被分散 这感觉不对。。。 有人同

我正在使用实体框架在N层Wpf应用程序中持久化数据。My dbcontext在所有存储库中共享,永远不会被释放。当我保存数据时,我将对象标记为已修改,并尝试保存更改。如果在保存对象时出现错误,该对象仍被标记为已修改,并且如果用户中止当前操作,则在保存另一个对象时将收到相同的错误

我通过在dbcontext中重写SaveChanges解决了这个问题,如果出现任何错误,我接受所有更改(请参阅下面的代码)。因此,如果对象发生错误,并且所有对象都被标记为未更改,即使它们未被分散

这感觉不对。。。 有人同意这个解决方案吗? 另一个解决方案是在我的repositores中的每个方法中创建dbcontext并立即处理它们。这将使我的存储库更加复杂和“单调”,我也将失去延迟加载数据的能力。。。 有人对我有不同的解决方案吗

    //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;
        }
    }

我们的团队采用类似于以下的方法:

存储库:

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方法以摆脱它。

拥有这样一个长期存在的上下文不是一个好主意。随着所有实体和更改被跟踪,它将变得庞大而缓慢,可能会出现与并发相关的问题,并且上下文引发的异常可能会影响整个应用程序

另一个解决方案是在我的 重新安置并立即处理。那会让我 存储库更加复杂和“noicy”,我也将失去 延迟加载数据的能力

在断开连接的场景中,我将创建并处理每个请求/工作单元。担心你的回购协议变得复杂?那么就不要使用这个额外的抽象层。回购协议真的有必要吗?直接使用DbContext有什么好处


至于延迟加载,我认为在断开连接的n层场景中,延迟加载并不真正合适。您可能应该使用急切加载视图所需的数据,或者使用单独的方法调用来获取相关数据。

考虑您的answear:)以清除我的数据库层是可操作的,我不公开实体框架中的任何内容。我只公开poco对象(代码优先),这样我就可以轻松地更改我的db层。我正在wpf客户机中使用db层,并计划在web应用程序和web服务中使用它。在后一种情况下,很容易在每次请求后处理上下文。我关心的是更新和处理上下文和性能的代码重复。你还认为你的解决方案对我来说是最好的吗?在您发送的链接中,说明“每个表单一个dbcontext”可能有效?为您的answear着想:)我已经考虑过您的解决方案,但对我来说,效果不太好。我正在使用TDD和依赖项。回购协议是通过我的业务逻辑中的构造函数注入发送的。对于您的解决方案,我必须为dbcontext设置一个工厂,为每个存储库设置一个工厂。这感觉像是将业务逻辑过度复杂化,并将业务逻辑与不相关的事项联系起来……在上面的业务逻辑中,dbcontext和存储库都可以通过构造函数注入来传递。正如我在回答中提到的,这只是一个简单的例子。如果您使用诸如dbcontext scope lifetime之类的关键字对Google进行一些研究,您会发现大多数ppl建议使用短期上下文。根据我自己的经验,我们发现了一个bug,其中有人忘记处理上下文,导致Web服务上的50ms查询需要3.2分钟才能执行。