为什么要在存储库中包含Repo.SaveChanges()方法?

问题描述 投票:4回答:3

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

我们正在考虑拥有一个可自动保存更改的存储库(例如快速而肮脏的示例):

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();
    }
}

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

c# entity-framework repository-pattern
3个回答
8
投票

每次更改后保存,将避免保存大量实体。在某些图形结构中,这可能是一个正确性问题,而在其他情况下,这只会导致CPU负载增加。 SaveChanges的成本不仅是写作,而且是遍历加载到上下文中的实体。

为什么要反对实体框架?做,它要做什么:保存批次并在对实体进行所有更改后最后调用SaveChanges

PersistCustomer方法的名称错误:它保留了所有内容,而不仅仅是客户。您不能使用EF保留单个实体。您的抽象(存储库)已损坏。

人们通常将EF包装在通用存储库中,该存储库不添加任何功能,但删除了功能。这对我来说从来没有道理。


0
投票

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

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

虽然它可能感觉像是多余地调用了“ SaveChanges”,但是第二种方法将允许您一次保存多个更改=无开​​销。

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


0
投票

我移至第一种方法有两个原因:

1]有时(不经常)我忘记调用SaveChanges()方法。例如,当我不得不同时提交一个事务(或者我保存了更改但忘记提交一个事务)并且我不理想的测试没有捕获到这种错误时(类似于您不调用Validate()的方法)每次您更改业务实体中的某项功能时都会起作用,因为您可以忘记调用它(即使这不是唯一原因))。

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

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

如果我需要在多个存储库上执行多项操作,则可以通过事务包装所有操作(可以在关系数据库中锁定所有微小的更改,以避免不一致或死锁,直到未整体提交事务为止。]]

但是我认为第一种或第二种方法没有更好的选择,两者都需要权衡取舍,这可能是个人喜好问题?

© www.soinside.com 2019 - 2024. All rights reserved.