4

我正在与另一位开发人员讨论是否要repo.SaveChanges()在我们的 Entity Framework 5 存储库中公开一个方法。

我们正在考虑有一个自动保存这样的更改的仓库(快速而肮脏的例子):

public class Repo {
    private OurEfContext _context = new OurEfContext();

    public void PersistCustomer(Customer cust)
    {
        // update customer code here
        _context.SaveChanges(); //  <-- is this okay?
    }
}

我们正在考虑的另一个选项是公开一个单独的 Repo.PersistChanges() 方法,如下所示:

public class Repo {
    private OurEfContext _context = new OurEfContext();

    public void PersistCustomer(Customer cust)
    {
        // update customer code here
        // no call to _context.SaveChanges();
    }

    public void PersistChanges()
    {
        _context.SaveChanges();
    }
}

我见过的大多数例子都使用第二种模式。一种模式比另一种更“正确”吗?

4

3 回答 3

8

每次更改后保存会阻止您保存批量实体。在某些图形结构中,这可能是一个正确性问题,在其他情况下,它只会增加 CPU 负载。的成本SaveChanges不仅仅是写作,还包括遍历加载到上下文中的实体。

为什么要针对实体框架工作?做,它想让你做的事:保存批次并SaveChanges在对实体进行所有更改后最后调用。

该方法PersistCustomer被错误地命名为:它持久化所有内容,而不仅仅是客户。您不能使用 EF 持久化单个实体。您的抽象(存储库)已损坏。

人们经常将 EF 包装在一个不添加任何功能但删除功能的通用存储库中。这对我来说从来没有意义。

于 2013-01-17T23:15:02.183 回答
3

我倾向于支持第二种方法。

第一个可能会“隐藏”保存操作,并且对用户来说看起来更好,但不要忘记您正在失去对保存操作的控制。如果您发现自己更新了多个实体,这将导致多个单独更改的开销,而不是让它们一次执行——这意味着更多的执行时间。

尽管它可能感觉像冗余地调用“SaveChanges”,但第二种方法将允许您一次保存多个更改= 没有开销。

我发现通过消除作为不必要的行为来提高性能的能力来限制自己。

于 2013-01-17T23:38:00.497 回答
1

我转向第一种方法有两个原因:

1)有时(不经常)我忘记调用SaveChanges()方法。例如,当我还必须提交一个事务(或者我保存了更改但忘记提交事务)并且我不理想的测试没有捕捉到这种错误时(类似于你不Validate()每次都调用函数的方法您更改了业务实体中的某些内容,因为您可能忘记调用它(即使这不是唯一的原因))。

2)存储库接口可以在内存存储库中转换(用于测试目的)并且没有任何调用意义SaveChanges(),这可能会造成混淆,因为标准集合没有这种方法并且应该为用户隐藏实现。

如果我需要添加一个集合,我可以在存储库中添加另一个方法Import(List<Customer> customers)执行foreach并在此之后调用SaveChanges()。这对用户来说也很清楚,存在一些优化的方法。

如果我需要对多个存储库执行多个操作,我可以将所有操作包装在一个事务中(每个微小的更改都可以锁定在关系数据库中以避免不一致或死锁,直到事务没有作为一个整体提交)。

但我不认为第一种或第二种方法更好,两者都有权衡,可能是个人喜好问题?

于 2020-01-02T19:05:05.877 回答