Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在存储库中包含Repo.SaveChanges()方法?_C#_Entity Framework_Repository Pattern - Fatal编程技术网

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

C# 为什么在存储库中包含Repo.SaveChanges()方法?,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,我正在与另一位开发人员讨论是否在EntityFramework5存储库中公开repo.SaveChanges()方法 我们正在考虑建立一个回购协议,自动保存这样的更改(快速而肮脏的示例): 我看到的大多数示例都使用第二种模式。一种模式比另一种模式更“正确”吗?每次更改后保存会阻止您保存实体批次。在某些图形结构中,这可能是一个正确性问题,在其他情况下,这只会增加CPU负载。SaveChanges的成本不仅仅是写入,还包括遍历加载到上下文中的实体 为什么要反对实体框架?执行,它希望您执行的操作:保存

我正在与另一位开发人员讨论是否在EntityFramework5存储库中公开
repo.SaveChanges()
方法

我们正在考虑建立一个回购协议,自动保存这样的更改(快速而肮脏的示例):


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

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

为什么要反对实体框架?执行,它希望您执行的操作:保存批处理,并在完成对实体的所有更改后调用
SaveChanges

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


人们通常将EF封装在一个通用存储库中,该存储库不添加任何功能,而是删除功能。这对我来说毫无意义。

我倾向于支持第二种方法

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

即使感觉像是重复调用“SaveChanges”,第二种方法将允许您一次保存多个更改=无开销。


我发现不必要地取消了提高性能的能力,从而限制了自己。

出于两个原因,我选择了第一种方法:

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

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

如果需要添加集合,我可以向存储库添加另一个方法
Import(列出客户)
execute
foreach
,然后调用
SaveChanges()
。用户也很清楚,存在一些优化的方法

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


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

我不知道你提倡哪种方法。在对实体进行所有更改后,最后调用
SaveChanges
。抽象没有中断,我也看不到通用存储库。您可能假设客户是一个EF实体,可能是这样,但它可能是一个实际的业务对象。存储库只是将客户映射到EF实体(可能不止一个)。这是正确的用法,因为存储库首先应该隐藏EF,这称为关注点分离,在这种情况下,存储库应该是工作单元的一部分,由比持久性更高的级别进行协调
public class Repo {
    private OurEfContext _context = new OurEfContext();

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