在我工作的公司,我被责令更新旧的MVC应用程序并为SQL数据库实现存储库模式。我已经使用Entity Framework Database- First创建了数据库的上下文,并获得了23个实体。
我需要为每个实体创建一个存储库还是为上下文实现一个通用存储库?我问这个问题是因为我在搜索互联网时发现了以下内容:
每个域一个存储库 您应该将存储库视为内存中域对象的集合。如果要构建名为Vega的应用程序,则不应具有如下所示的存储库: public class VegaRepository {} 相反,您应该为每个域类拥有一个单独的存储库,例如OrderRepository,ShippingRepository和ProductRepository。 资料来源:用Mosh编程:存储库模式的4个常见错误
每个域一个存储库
您应该将存储库视为内存中域对象的集合。如果要构建名为Vega的应用程序,则不应具有如下所示的存储库:
public class VegaRepository {}
相反,您应该为每个域类拥有一个单独的存储库,例如OrderRepository,ShippingRepository和ProductRepository。
资料来源:用Mosh编程:存储库模式的4个常见错误
通用存储库是否适用于实体框架数据库优先?这是因为我在搜索互联网时发现了以下内容:
实体框架 请注意,只有在先使用代码映射POCO的情况下,存储库模式才有用。否则,您将改为通过实体来破坏抽象(=然后,存储库模式不是很有用)。您可以按照这篇文章,如果你想为你生成一个基础。 来源:CodeProject:存储库模式,正确完成
实体框架
请注意,只有在先使用代码映射POCO的情况下,存储库模式才有用。否则,您将改为通过实体来破坏抽象(=然后,存储库模式不是很有用)。您可以按照这篇文章,如果你想为你生成一个基础。
来源:CodeProject:存储库模式,正确完成
首先,如果您使用的是完整的ORM,例如Entity Framework或NHibernate,则应避免实现存储库和工作单元的附加层。这是因为; ORM本身公开了通用存储库和工作单元。 如果是EF,则您DbContext是工作单位,并且DbSet是通用存储库。如果是NHibernate,它ISession本身就是。 在相同的现有存储库上构建通用存储库的新包装是重复的工作。为什么要重新发明轮子?
DbContext
DbSet
ISession
但是 ,有人认为直接在调用代码中使用ORM存在以下问题:
除了上述所有以外,通常讨论的另一个问题是“如果我们决定将来更改ORM,该怎么办”。这不是决策时的重点,因为:
考虑到上述四个问题,即使您使用的是完整的ORM,也可能有必要创建存储库-但是, 这是根据情况决定的 。
即使在这种情况下,也必须避免使用通用存储库。它被认为是反模式。
为什么通用存储库是反模式的?
GetById()
我建议你阅读这些(1,2,3,4,5)的文章解释了为什么通用存储库是一个反模式。这等回答论述了一般Repository模式。
因此,我建议:
无论如何,请勿将通用存储库暴露给调用代码。
另外,请勿IQueryable从具体存储库中返回。这违反了存储库存在的基本目的- 抽象数据访问。通过IQueryable在存储库外部进行公开,许多数据访问决策都会泄漏到调用代码中,并且存储库失去了对其的控制。
IQueryable
我需要为每个实体创建一个存储库还是为上下文实现一个通用存储库
如上所述,为每个实体创建存储库是更好的方法。请注意,存储库最好返回域模型而不是实体。但这是另一个讨论的话题。
通用存储库可用于EF Database First吗?
如上所述,EF本身公开了通用存储库。在上面再建一层是没有用的。您的图片在说同样的话。