1

我有一个用 C# 编码的 ASP.NET MVC 应用程序。该应用程序的结构如下:

  1. 控制器

  2. 存储库

  3. LINQ to Entity(实体框架)

  4. 看法

我使用 Repository( _ProductRep) 来查询 LINQ to Entities 并将实际实体提供给控制器List<T>,或者不提供IQueriables<T>

对于我有更多疑问的情况,我想获得一些帮助。我有以下代码:

List<Monthly_Report> lproduct_monthlyReport = _ProductRep.GetArchiveReport(product.Prod_ID, lmonth, lyear);

在我得到这个之后,lproduct_monthlyReport我需要在 foreach 中查询它并获取一个特定的记录。目前我实现了这样的解决方案:

foreach (var item in litemList)
{    
   var lproductItem_monthlyReport = lproduct_monthlyReport.Single(m => m.Item_ID == item.Item_ID);
   // Other code
} 

litemList产品可以拥有的所有可能项目的列表在哪里。

我想知道这个解决方案是否明智地增加了耦合(并且违反了Demeter 定律)或者它是可以接受的,因为我实际上是在查询 aList<T>而不是 a IQueriable<T>。如果我错了,请纠正我,但我猜由于 List 不需要访问 EF DataContext,因此 Controller 和 EF 之间没有耦合。

如果我错了,我能想到的唯一解决方案是用 Repository 方法替换查询(我仍然必须实现):

var lproductItem_monthlyReport_ProductRep.GetArchiveReport(product.Prod_ID, lmonth, lyear, item.Item_ID);

但是,使用此解决方案,存储库在每个循环周期中使用 4 个条件进行一次查询,而在之前的解决方案中,存储库仅使用一个条件进行查询。

能否请您就这个问题赐教?谢谢。

PS:我需要两个变量lproduct_monthlyReportlproductItem_monthlyReport循环内部,我不能只使用其中一个

PPS:我知道我应该在 Controller 和 Repository 之间建立一个业务服务层,这是我的下一步。

4

2 回答 2

2

从存储库中返回列表会给你带来糟糕的性能,因为你失去了延迟执行的行为。基本上,您的存储库会将每条记录(而不是相关实体)检索到内存中,并将它们转换为列表,然后在内存中进行处理。如果要访问相关实体,则需要另一个数据库命中。如果您坚持使用 IEnumerable(或 IQueryable),那么您将向客户端隐藏实体框架行为的细微差别,但仍然可以获得延迟加载和延迟执行等优势。

现在忽略存储库的细节,如果你这样做:

List<Product> products = MyEntities.Products.ToList();

Product product1 = products.Single(p => p.Id = 1);

它的表现会比这差得多:

IEnumerable<Product> products = MyEntities.Products;

Product product1 = products.Single(p => p.Id = 1);

第一个将在没有 WHERE 子句的数据库中执行 SELECT,然后为每个结果实例化 .Net 对象,然后查询该内存列表。在您访问 product1 上的属性之前,第二个将不执行任何操作,并且此时将发出数据库命令以仅检索 1 个产品,并且仅实例化该 1 个产品。

2 之间的差异对于小数据集可能并不明显,但随着数据集变大,这种差异会越来越严重。加入一个连接的实体(或更糟糕的实体集合),你可能会获得数千个数据库命中,如果你坚持使用 IEnumerable,你会得到 1。

于 2011-04-13T13:14:23.930 回答
1

我可能会有这样GetArchiveReport(int prodID, int lmonth, int lyear, IEnumerable<int> itemIDs)的功能,可以在您的查询中执行 itemIDs.Contains(tbl.ID)

var SelectedReports = _ProductRep.GetArchiveReport(product.Prod_ID, lmonth, lyear, litemList.Select(item => item.Item_ID));
foreach(var prodItem in SelectedReports)
{
  //Do code
}
于 2011-04-13T13:07:01.320 回答