C# 为什么要抽象ORM?

C# 为什么要抽象ORM?,c#,orm,repository,abstraction,C#,Orm,Repository,Abstraction,我经常看到使用存储库模式来抽象ORM的代码。为什么要这样做?ORM本身不是一个抽象概念,并充当存储库吗 两者之间有很大区别吗 public class EmployeeRepo { GetById(int id) { //Access ORM here }; } 消费数据: public class MyController{ private EmployeeRepo = _Repo = new EmployeeRepo(); public ActionResult

我经常看到使用存储库模式来抽象ORM的代码。为什么要这样做?ORM本身不是一个抽象概念,并充当存储库吗

两者之间有很大区别吗

public class EmployeeRepo 
{
    GetById(int id) { //Access ORM here };
}
消费数据:

public class MyController{
    private EmployeeRepo = _Repo = new EmployeeRepo();

    public ActionResult ShowEmployee(int id)
    {
        var emp = _Repo.GetById(id);
        //Versus
        var emp = ORM.Where(e => e.Id == id);

        return View(emp);
    }
}

为什么我要重新创建ORM已经提供给我的东西?

这通常是过度工程的结果,但如果您可能切换ORM,最好将您的ORM封装在一个类中,该类的契约即您控制的公共/内部方法。通过这种方式,您可以简单地修改类(或者在编程到接口的情况下插入不同的类)以切换ORMs。否则,您必须从所有代码中取消直接ORM调用的实现,并在其位置重新实现新调用,这可能需要数百到数千行代码,具体取决于项目的复杂性

我经常看到使用存储库模式来抽象ORM的代码

99.(9%)的项目不需要这样做。程序员们似乎欣喜若狂,因为他们可以在抽象之上创建另一个抽象

为什么我要重新创建ORM已经提供给我的东西

你不应该这样做,事实上,你制造了更多的问题,举几个例子:

  • 客户是否明确要求该功能在ORM之间轻松切换?真正地你有预算吗
  • 您已经准备好为您的抽象引入测试覆盖,您有时间和金钱来完成这项工作
  • 你有日志框架吗
  • 你考虑设计时间来找出你能支持的通用API吗?缓存、分片、负载分布、存储过程和触发器呢
  • 您是否准备花时间升级到几个ORM的新版本,是否准备好修复破坏性的更改

更好的是,使用ORM本身的接口/基类,这样您就可以轻松地测试和模拟它。

我知道这是一个老问题,但这个主题非常有趣

我同意直接使用ORM更容易,而且在简单的项目中使用ORM可能是正确的

但如果您正在开发长期存在的复杂系统,那么业务逻辑中对ORM的直接依赖意味着您在很多地方都依赖于ORM。由于破坏了ORM中的更改,或者仅仅因为您决定以其他方式执行某些操作,这将不可避免地在将来产生问题

所以,抽象ORM与其说是简单地切换ORM的能力,不如说是将您的项目从外部依赖中分离出来(由于流行的ORM的复杂性和持续开发,在流行的ORM中破坏更改的可能性很高)。另外,拥有这样一个解耦的体系结构,您将获得项目良好的可测试性作为奖励


如果你不想自己做这个抽象,有一些项目(例如)可以帮助你做到这一点。当然,这意味着您将反过来依赖于这些框架,但这些框架负责处理不同的ORM(并破坏该ORM中的更改),为您提供实际上永远不会更改的抽象和统一语法。

如果您有一个“通用”存储库层,您独立于实际使用的ORM/数据库。它还充当一个层,可以独立于实际数据库进行测试。但显然,这需要更多的工作,因此在小型应用程序中可能没有意义。但是在一个企业开发环境中,有几十个开发人员在使用这个应用程序,拥有一个不需要任何实际数据库/ORM知识或经验的单一存储库层要容易得多。@marc_s如果您使用存储库来描述您正在使用的数据库和实现,我可以理解,但ORM已经做到了这一点,因此,开发人员不必知道任何特定于数据库的信息,除非在某些情况下。我认为从事项目的开发人员应该对正在使用的技术有很好的理解,否则他们可能会错误地使用它,就像任何框架一样,有最佳实践。