19

存储库模式用于从特定数据库和对象关系映射技术(如EF)抽象使用。因此,如果我决定这样做,我可以很容易地将(例如)我的Entity框架映射替换为Linq to SQL。存储库模式与实体框架

但是,当我使用EF我有我的实体类从模型 - 也就是他们从该视觉图生成。如果我在存储库中使用这个生成的实体类,然后决定用其他东西替换EF,那么我将删除该可视化实体图,这意味着还要删除类吗?

我正在处理的一点是,我的存储库将依赖实体框架,即在数据访问层上,因为它将使用由EF生成的类。

我该如何消除这种依赖性?

另请注意,我主要使用EF是因为它能够从该视觉图生成所有内容 - 我只是设计图并让它为所有外键生成数据库等。我非常喜欢这一点,不想考虑SQL命令。

回答

27

存储库始终依赖于数据访问技术。这就是人们使用存储库的原因 - 将数据访问依赖关系包装到单独的图层。如果你决定改变数据访问技术(你可以做1%的机会),你将不得不创建新的存储库,实现与以前相同的界面。

介绍repositoris将增加一个新的复杂层。存储库有其优点和缺点。只是因为“你可以改变未来的数据访问方式”而引入它们是一个不好的理由。不要因为可能发生的事情而设计你的应用程序。根据当前实际需求设计应用程序(敏捷方式),并在需要更改时重构代码 - 这是如何在市场上具有竞争力的唯一方法。功能是销售你的软件而不是其开放式架构,用于任何类型的变更(好吧,有例外,但在这种情况下,开放架构是最高级别的要求)。

当使用EF可以有几种选择如何创建实体:

  • 使用对自定义工具来生成实体对象。这是为EDMX创建“代码隐藏”文件的默认方法。它是EFv1(.NET 3.5 SP1)中唯一可用的解决方案。
  • 使用T4模板来生成实体对象,POCO,STE或任何自定义实体类型(您可以修改生成逻辑)。这通常用于EFv4。
  • 自己写POCO。这可以与EFv4一起使用,并且它始终与EF 4.1中的代码优先方法一起使用。

如果您希望数据访问技术在未来可以改变,可以使用POCO的第二种或第三种方法。在T4模板的情况下,您可以简单地复制生成的POCO或修改项目文件,以便在删除EDMX文件后不会丢失它们。

如果你是不知道,如果第二或第三种方法适合你看看我这些问题的答案:

因为我不知用@ Patko的答案同意你还应该检查Ayende's blog。他已经写了几篇关于使用存储库和构建应用程序的文章。他正在撰写有关NHibernate的文章,但是可以使用EF进行类似的裁决。唯一的区别是NHibernate提供了更好的抽象,所以直接使用NHibernate的代码更好的可测试性。

+0

@Ladislav Mrnka首先我不同意“不要设计你的应用程序,因为可能发生的事情”。我总是试图使我的代码更加健壮和防守,并且通常会在以后证明这是一个很好的决定。几乎没有多余的行意味着在重构和调试时节省了数小时。如果“由于可能发生的事情而不设计你的应用程序”是真的,那么许多项目根本不会使用存储库(除了那些需要从一开始就支持2种永久存储技术的应用程序之外)。其次,我只是感觉不好,因为我需要一些DAL来包装它。 – drasto 2011-03-23 09:05:00

+0

@Ladislav Mrnka +1为T4模板和这些链接。有关于此的更多资源? – drasto 2011-03-23 09:12:40

+1

@drasto:如果你足够熟练地对你的架构做出专业决定,那么这种方法就没问题。但是在回答和阅读许多有关EF和知识库的问题之后,我只是认为许多开发人员都在构建他们的应用程序。从一开始就有两种数据访问技术是引入存储库的一个很好的理由,但您在问题中没有提到它。 – 2011-03-23 09:15:37

3

实体框架版本4的一个新功能是“Code First”开发。这将允许您在实体框架中使用常规的C#(POCO)类。一旦以这种方式编写了类,就可以编写一个不同的存储库实现,它们使用不同的机制来保存这些类。

ScottGu有一个blog post包含更多信息。

+1

其实这是不EFv4的特征。它是独立的版本,称为EF 4.1。 – 2011-03-23 08:11:47

+0

+1我喜欢。不仅因为拥有独立的类,而且还因为每当我对模型类进行更改时都可以重新创建数据库。但是有一些东西我不喜欢 - 这是不必编写的所有类和它们的属性 - 我希望我的模型有大约50-70班。在视觉设计师看来好多了。所以,我希望这样的事情“1.创建可视化模型图2.拥有VS产生从图3有无EF POCO类来生成表从POCO类外键等,或(甚至更好)有一些其他的工具生成EF图POCO clases” – drasto 2011-03-23 08:27:23

+0

@drasto - 与EF的设计师一种常见的批评是它是如何与笨重量好实体使用。奇怪你有相反的问题。 @Sean Reily - 你的回答是不正确的。 4.1中的“代码优先”并不支持您使用POCO类,这在4.0中是可能的。 MS后来发布了t4模板,使这更容易。 http://visualstudiogallery.msdn.microsoft。com/23df0450-5677-4926-96cc-173d02752313 – jfar 2011-03-23 12:31:45

7

从一种持久性技术转换到另一种持久性技术的能力很好,而且都很好,但是你真的需要吗?

首先,什么是存储库?它提供了对域对象的内存中类似集合的访问。但是每个现代的ORM工具都已经这么做了,所以另一个抽象层次就增加了一些复杂性。其次,从一种持久性技术切换到另一种持久性技术通常比提供另一种库实施更复杂。例如,你打算如何处理交易?事务通常依赖于上下文,并在仓库之外处理。您当然可以使用某种工作单元实现,但是您必须为每个持久性技术实现新的工作单元。

我不是故意说你不应该使用存储库,只是可能给它另一个想法。

+0

我仍在考虑我的选择。我有ASP.NET MVC应用程序,其持久性只是想工作......它设计得很糟糕。所以我必须从头开始重新构建它,以便能够根据开发业务逻辑需求(我现在正在开发的)开发轻松更改模型。那么你建议我做什么?我应该只是将'ObjectContext'的实例传递给服务层中的服务?我觉得有点不好... – drasto 2011-03-23 09:14:07

+2

+1,因为我同意它。仓库被过度使用,并且在任何现代ORM工具存在之前就定义了它。 – 2011-03-23 09:19:53

+3

也许你可以看看Ayende的博客http://ayende.com/Blog/default.aspx。他是存储库模式的支持者之一,但他改变了主意。它从http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx博客文章开始。他的最新帖子也提供了一些关于如何去做的想法。至于'ObjectContext',我不明白为什么不。如果你通过知识库会感觉好点?只要看看'ObjectContext'作为一种存储库:) – Patko 2011-03-23 09:23:04

6

EF设计者创建的实体类在您的项目中,在您的“Model.Designer.cs”中。您可以复制代码,以便您的实体保留在您的项目中,即使您从EF中删除模型或引用。 但是,它们与EF紧密耦合,因此您应该努力将EF从实体类中解耦。

到现在为止,你有T4模板,可以帮助你的脱钩,但他们仍然需要一些改变选择的T4:

  • ADO.NET EntityObject生成
  • ADO.NET POCO实体发生器
  • ADO.NET自跟踪实体发生器

EF4.1带来了一个简化的API,DbContext,可以在您想要分离实体类时提高EF的体验。用EF4。1你的方法3:

  • 代码首先
    • 您创建的类和EF创建DB,因为它应该是
    • 类不会自动消失,当你删除对EF
    • 引用
    • 你不会有任何设计师
  • 数据库优先
    • 如果你已经有一个数据库,模型会为您创建设计者
    • 您可以用新的T4模板创建自己的实体类的DbContext发电机
  • 机型第
    • 如你现在已经做的那样,你在设计器中创建你的模型
    • 你可以用DbContext生成器创建实体类

现在回答你的问题:

如何删除这种依赖?

  1. 安装EF4.1
  2. 创建模型(使用模型第一种方法)
  3. 从模型生成数据库
  4. 用的DbContext发电机

生成实体类看看你如何在这里做到这一点:EF 4.1 Model & Database First Walkthrough
你应该阅读ADO.NET团队博客Using DbContext in EF Feature CTP5 Part 1: Introduction and Model(EF4.1前身为EF功能CTP5)系列。
你可以在我的问题更多的细节:EF POCO code only VS EF POCO with Entity Data Model

+0

+1现在你是这里的明显赢家。我决定使用T4模板来生成POCO实体,然后尝试找出当我更改模型时如何使框架自动重新创建数据库表。不过我更喜欢你的建议 - 看起来用简化的API然后用T4模板做起来更容易。我还有一个问题:在使用Model First方法时,每次更改我的模型时是否可以让我的数据库表与POCO类一起自动重新创建?我该怎么做 ? – drasto 2011-03-23 18:32:30

+0

我知道代码第一种方法可能自动生成表格代码第一种方法 – drasto 2011-03-23 18:40:40

+0

我已经问过你的答案在这里受到启发的另一个问题,请随时张贴一些答案http://stackoverflow.com/questions/5410381/generate-poco-classes -from-model-using-t4-templates-vs-ef4-1-simplified-api-mode。无论如何谢谢 – drasto 2011-03-23 19:28:03