0

我正在使用实体框架将数据持久保存在 N 层 Wpf 应用程序中。我的 dbcontext 在所有存储库中共享,并且从未被处置。当我持久化数据时,我将对象标记为已修改并尝试保存更改。如果在持久化对象时发生错误,则该对象仍被标记为已修改,并且如果用户中止当前操作,他将在保存另一个对象时得到相同的错误。

我通过在我的 dbcontext 中覆盖 SaveChanges 解决了这个问题,如果出现任何错误,我接受所有更改(参见下面的代码)。因此,如果对象发生错误并且所有对象都被标记为不变,即使它们没有被持久化。

这感觉不对……有人同意这个解决方案吗? 另一种解决方案是在我的存储库中的每个方法中新建 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;
        }
    }
4

2 回答 2

0

拥有如此长久的背景并不是一个好主意。随着跟踪所有实体和更改,它会变得又大又慢,可能会出现与并发相关的问题,并且您的上下文抛出的异常可能会影响您的整个应用程序。

http://msdn.microsoft.com/en-us/data/jj729737

另一种解决方案是在我的存储库中的每个方法中新建 dbcontext 并立即处理它们。这将使我的存储库更加复杂和“嘈杂”,并且我还将失去延迟加载数据的能力

在断开连接的情况下,我将创建并处理每个请求/工作单元。担心您的回购变得复杂?然后不要使用这个额外的抽象层。回购真的有必要吗?直接使用 DbContext 有什么好处?

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

于 2013-04-29T06:53:11.547 回答
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 Controller 中实例化 dbcontext 并覆盖 Dispose 方法以摆脱它。

于 2013-04-29T00:19:54.627 回答