Linq 如果实体框架要与POCO一起工作,那么为什么要依赖IObjectSet?

Linq 如果实体框架要与POCO一起工作,那么为什么要依赖IObjectSet?,linq,entity-framework,design-patterns,orm,poco,Linq,Entity Framework,Design Patterns,Orm,Poco,我一直听说EF4.0、POCO、IObjectSet、UnitOfWork(顺便说一句,我第一次听到UoW时,UoW至少有17岁以上)等等 所以有些人谈论存储库“模式”。等等。有许多博客展示他们的“包装”或存储库或类似的东西的混合物。 但它们都需要IObjectset(或者在某些情况下是IQueryables)挂起它们的POCO。期望似乎是您可以针对它们编写查询 所以,如果一个人需要IObjectSet,而不仅仅是IList或其他更简单的集合,为什么我们要说这是POCO且不受EF影响 如果我想从

我一直听说EF4.0、POCO、IObjectSet、UnitOfWork(顺便说一句,我第一次听到UoW时,UoW至少有17岁以上)等等

所以有些人谈论存储库“模式”。等等。有许多博客展示他们的“包装”或存储库或类似的东西的混合物。 但它们都需要IObjectset(或者在某些情况下是IQueryables)挂起它们的POCO。期望似乎是您可以针对它们编写查询

所以,如果一个人需要IObjectSet,而不仅仅是IList或其他更简单的集合,为什么我们要说这是POCO且不受EF影响


如果我想从下面交换EF,我需要确保我的“其他”O/R映射器(我知道我知道..EF不仅仅是一个O/R映射器)理解IObjectSet,并且能够解析查询中的ExpressionTrees、执行以及其他行为与EF类似

首先查看实体框架代码:

首先查看实体框架代码:

回应短语:“如果我想从下面交换EF”:

在我的业务中,我更可能调出数据库,比如从Oracle到SQL Server(反之亦然),而不是调出数据访问框架。另一方面,确实存在使EF成为有利选择的选项


除EF提供的LINQ提供商外,还有其他LINQ提供商(如LLBLGen)。当然,将EF数据层替换为NHibernate或EasyObject会很困难,因为这些框架没有足够的特性奇偶性来简化转换;然而,LINQ旨在为其他LINQ提供商提供介入并提供他们自己的解决方案开辟道路。

针对“如果我想从下面交换EF”这句话:

在我的业务中,我更可能调出数据库,比如从Oracle到SQL Server(反之亦然),而不是调出数据访问框架。另一方面,确实存在使EF成为有利选择的选项


除EF提供的LINQ提供商外,还有其他LINQ提供商(如LLBLGen)。当然,将EF数据层替换为NHibernate或EasyObject会很困难,因为这些框架没有足够的特性奇偶性来简化转换;然而,LINQ的设计目的是为其他LINQ提供商提供介入并提供他们自己的解决方案开辟道路。

IObjectSet不是构成实体POCO的接口,它只是持久性容器IObjectSet。POCO的要点是防止您必须从EF4中T4 POCO模板提供的EF类型派生模型类


存储库模式是来自ORM的可选附加抽象层,以便在需要时更容易地实现不同的抽象层。关注点分离等。

IObjectSet不是构成实体POCO的接口,它只是持久性容器IObjectSet。POCO的要点是防止您必须从EF4中T4 POCO模板提供的EF类型派生模型类


存储库模式是来自ORM的可选附加抽象层,以便在需要时更容易地实现不同的抽象层。关注点分离等。

您的问题包含错误的陈述:正确的是POCO不依赖于IObjectSet

POCO本身独立于EF。或者更好:它们应该独立于EF。因为您正在实现POCO类,所以您最终要负责确保这一点。(否则,术语POCO将是错误的。)

如果您使用标准T4模板从模型描述创建POCO类,而不是自己编写类,则该模板可确保类不依赖于EF-它们不是从
实体
派生的,并且作为类成员的集合由该模板通过
ICollection
生成,不适用于IObjectSet

存储库模式是另一个问题。POCO T4模板不会将存储库创建为抽象接口,以便使用POCO操作数据库。它创建了一个派生的ObjectContext,它是可能的存储库接口的特定于EF的实现(或者至少有助于轻松实现可能的存储库接口)

如果您想拥有一个不依赖于EF或LINQ的存储库接口,您必须这样定义它。没有任何东西强迫您在该接口中使用IObjectSet或IQueryable。也许您看到的实现存储库模式的示例并不打算独立于实体框架或LINQ

例如:

假设,在业务层中,您需要一个从持久层返回的给定类别的所有产品的列表。该层将公开什么来满足请求

如果您只考虑提供LINQ提供程序的数据库,您可以这样设计存储库接口:

public interface IProductsRepository
{
    IQueryable<Product> AllProducts { get; } // Product is the POCO class
}
但是,如果您想更开放地支持哪种类型的持久性存储,那么最好设计独立于IQueryable的存储库。其结果可能是您的抽象存储库接口需要更具体的方法来回答来自业务层的请求,例如,您现在需要:

public interface IProductsRepository
{
    IList<Product> GetProductsOfCategory(string category);
}
使用EF(或另一个支持LINQ的数据框架)对该存储库的具体实现仍然可以像第一个示例中的业务层一样利用LINQ查询。但其他实现可以以另一种方式工作(例如:您有一个“数据库”,它将产品存储在每个类别的一个文本文件中。然后该接口方法的实现将从磁盘读取一个特定文件。或者您的存储库实现向Web服务请求数据,等等……)

关键点是:如果您使用的是POCO类,那么您可以使用所有这些类型的存储库。具有POCO支持的EF不会强制您构建存储库int
public interface IProductsRepository
{
    IList<Product> GetProductsOfCategory(string category);
}
IProductsRepository rep = new SomeConcreteImplementationOfProductsRepository();
IList productsOfCategory = rep.GetProductsOfCategory("stuff");