9

阅读答案后,请在问题末尾阅读我的更新:

我正在尝试应用Rob Conery他的博客MVC Storefront ”下描述的存储库模式。但是我想问一下我在应用这种设计模式之前遇到的一些问题。

Rob 制作了自己的“模型”并使用一些 ORM“LINQ to SQL 或实体框架 (EF)”将他的数据库映射到实体。

然后他使用了自定义存储库,在这些存储库中,他在 ORM和他的IQueryable<myModel>之间进行了某种 映射或“解析” 。EntitiesModel

我在这里问的是:

是否可以在 ORMEntities和我的模型“ classes”之间进行自定义映射并仅加载我想要的属性?我希望这一点很清楚。

POCO 更新

**

这是我在许多建议和许多尝试后决定的:

**

毕竟,关于 Rob Conery 先生的意见,我有更好的解决方案:

  1. 我将模型构建为“ POCOs”并将它们放在我的“模型层”中,因此它们与“edmx”文件无关。
  2. 建立我的存储库来处理这个“ POCO”模型依赖于“ DbContext
  3. 然后我创建了一个“ ViewModels”来从这些存储库中获取视图所需的信息。

所以我不需要“EF 模型”和“我的模型”之间再添加一层。我只是稍微扭曲我的模型并强制 EF 处理它。

正如我所见,这种模式比 Rob Conery 的模式要好。

4

4 回答 4

19

是的,如果您使用的是 LINQ to SQL,这是可能的。您需要做的就是使用投影将您想要的数据提取到您选择的对象中。您不需要所有这些带有接口和诸如此类的装饰 - 如果您使用特定于视图的模型(听起来像您需要的) - 创建一个 ViewModel 类。

我们称之为 ProductSummaryView:

public class ProductSummaryView{
   public string Name {get;set;}
   public decimal Price {get;set;}
}

现在从存储库中加载它:

var products= from p in _repository.GetAllProducts
              where p.Price > 100
              select new ProductSummaryView {
                  Name=p.ProductName,
                  Price=p.Price

              }

这将提取价格 > 100 的所有产品并返回 IQueryable。此外,由于您只要求两列,因此在 SQL 调用中将只指定两列。

于 2010-02-25T18:20:20.173 回答
3

不是回避您的问题,但最终由您决定存储库的工作方式。

高级前提是您的控制器将指向某个存储库接口,例如IRepository<T> where T : IProduct. 它的实现可以做很多事情——从磁盘加载整个数据库并存储在内存中,然后解析 LINQ 表达式以返回内容。或者它可以只返回一组固定的虚拟数据用于测试目的。因为您正在使用存储库接口,所以您可以拥有任意数量的具体实现。

现在,如果您正在寻找对 Rob 特定实现的批评,我不确定这是否与 Stack Overflow 密切相关。

于 2010-02-16T10:26:37.443 回答
2

虽然可以使用查询(与存储库模式无关)基于对该对象的列子集的查询来填充对象的一部分,但这并不是“通常”完成的方式。

如果你想返回一个对象的子集,你通常会创建一个只包含该属性子集的新类。这通常(在 MVC 世界视图中)被称为 View Model 类。然后,您使用投影查询来填充该新类。

无论您是否使用存储库模式,您都可以完成所有这些工作。我认为这两个概念之间没有冲突的重叠。

于 2010-02-16T15:13:44.053 回答
2

延迟加载

请记住,IQueryable 将所有加载推迟到最后一个负责任的时刻。您可能不必使用 LINQ 运算符加载所有数据来获取所需的数据。; )

尊重视图中域类的依赖关系,我会说不。为此使用 ViewModel 模式。它更易于维护;您可以使用AutoMapper来避免映射问题,它们在复合视图场景中非常灵活 :)

根据新问题...答案是肯定的,你可以。正如 Rob Conery 所说,使用投影;):

var query = from p in DataContext.Persons}
select new Persons
{
  firstname = p.firstname,
  lastname = p.lastname
});
于 2010-02-16T16:30:25.133 回答