【问题标题】:How to create and populate a nested ViewModel well如何很好地创建和填充嵌套的 ViewModel
【发布时间】:2010-11-01 23:54:21
【问题描述】:

我有一个严重嵌套的视图模型。我需要从 Entity Framework 4 填充它。我尝试创建一个大的 linq 语句来填充它,但它说它不识别 .ToList() 方法。它编译得很好。运行时错误是

LINQ to Entities does not recognize the method 
'System.Collections.Generic.List`1[ProductDepartment] ToList[ProductDepartment]
(System.Collections.Generic.IEnumerable`1[ProductDepartment])' method, 
and this method cannot be translated into a store expression.

在不进行数千次数据库调用的情况下填充此类内容的更有效方法是什么?

List<Product> Products {
    int ID
    string Name
    ...
    List<Department> Departments {
        int ID
        string Name
    }
    List<Image> Images {
        int ID
        string Name
    }
    List<Price> Prices {
        int ID
        string Name
        List<Version> Versions {
            int ID
            string Name
            List<Pages> Pages {
                int ID
                string Name
}   }   }   }

可怕的 Linq 代码看起来像这样

var myProducts = (from myProduct in DC.MyProducts
                  where p => p.productGroup == 1
                  select new Product {
                      ID = myProduct.ID,
                      Name = myProduct.Name,
                      Departments = (from myDept in DC.MyDepartments
                                     where q => q.fkey = myProduct.pkey
                                     select new Department {
                                         ID = myDept.ID,
                                         Name = myDept.Name
                                     }).ToList(),
                      ...
                      //Same field assignment with each nesting
                  }).ToList();

更新:

解决方法是删除所有 .ToLists(),反正效果更好。

现在我必须对最终产品进行过滤和排序。

【问题讨论】:

  • 启用预加载,使用 .include();参考:blogs.msdn.com/b/adonet/archive/2008/10/07/…
  • 这是一个非常好的主意,但它正在加载嵌套。我检查并删除了所有 .ToLists(),将返回类型更改为 IEnumerable,然后在对象上执行了 .ToList()。然后一切都开始流动。仍在寻找最好的方法来做到这一点。 :)

标签: c# entity-framework-4


【解决方案1】:

首先,这是一个疯狂的模型,但我假设你已经知道这一点。

你真的需要一下所有这些信息吗?

我将在这里扮演魔鬼的拥护者并假设你这样做,在这种情况下你有几个合乎逻辑的选择:

1) 正如@xandy 提到的 - 使用 .Include 在一次调用中急切加载您的关联。这是假设您在 EDMX 中为您的实体设置了导航属性。

2) 使用视图。将所有疯狂的连接逻辑放入数据库中,使您的 EF 工作成为一个非常简单的视图选择。这样做的缺点是您对视图的查询基本上变成只读的,因为我不相信您可以对映射到视图的实体执行更新。

所以这是您的选择 - 如果这是用于显示数据的只读集合,请使用视图,否则一键立即加载您的关联。

另外,编写 LINQ 查询时要小心 - 我看到您有多个 .ToList 语句,这将导致查询被执行。

构建您的查询,然后在最后执行一次 .ToList。

【讨论】:

  • 回答你的问题,有导航属性,视图是一个绝妙的主意(虽然会有很多冗余信息)视图模型无论如何都是只读的,它需要我删除所有的 .ToList () 因为它们由于某种原因不存在(无论如何工作得更好),好建议!
  • 我将此标记为答案,因为从技术上讲,由于嵌套的 ToLists(),它无法正常工作,您的建议是删除它们,这就是答案。下一个问题是排序和过滤。
【解决方案2】:

为什么您需要一次性获取所有这些信息?访问嵌套属性时可以使用延迟加载吗?

【讨论】:

  • 网站。在 300 毫秒内提取所有数据更快,因为每个网站请求有 300 毫秒的延迟。我们做分页,但他们有 600 种产品,想一次看到尽可能多的产品。超过 600 个产品的每个产品(6 个部分)的两秒延迟会很糟糕。
猜你喜欢
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 2015-04-08
  • 2015-10-23
相关资源
最近更新 更多