【问题标题】:Linq filter collection with EF使用 EF 收集 Linq 过滤器
【发布时间】:2009-12-10 15:13:45
【问题描述】:

我正在尝试让实体框架同时选择一个对象并过滤其集合。我有一个包含作业集合的 JobSeries 对象,我需要做的是按 ID 选择一个作业序列并按 SendDate 过滤所有作业,但我无法相信这个简单的查询有多么困难!

这是有效的基本查询:

 var q = from c in KnowledgeStoreEntities.JobSeries
                    .Include("Jobs.Company")
                    .Include("Jobs.Status")
                    .Include("Category")
                    .Include("Category1")
                where c.Id == jobSeriesId
                select c;

任何帮助将不胜感激,我一直在尝试在谷歌中找到一些东西,我想做的是:http://blogs.msdn.com/bethmassi/archive/2009/07/16/filtering-entity-framework-collections-in-master-detail-forms.aspx

虽然它在 VB.NET 中,但我无法将其转换为 C#。

编辑:我现在已经尝试过了,但它不起作用!:

            var q = from c in KnowledgeStoreEntities.JobSeries
                                      .Include("Jobs")
                                      .Include("Jobs.Company")
                                      .Include("Jobs.Status")
                                      .Include("Category")
                                      .Include("Category1")
                    where (c.Id == jobSeriesId & c.Jobs.Any(J => J.ArtworkId == "13"))
                    select c;

谢谢

【问题讨论】:

  • 你能解释一下“过滤”是什么意思吗?您想要某个日期范围内的对象吗?
  • 基本上我想选择一个 id = 1 的 JobSeries 并从 Jobs 的子集合中选择 Job.SendDate = 01/12/2009 的所有内容。谢谢

标签: linq entity-framework


【解决方案1】:

Include 会引入性能问题。 保证延迟加载会引入性能问题。投影既便宜又简单:

var q = from c in KnowledgeStoreEntities.JobSeries
        where c.Id == jobSeriesId            
        select new 
        {
             SeriesName = c.Name,
             Jobs = from j in c.Jobs
                    where j.SendDate == sendDate
                    select new
                    {
                        Name = j.Name
                    }
             CategoryName = c.Category.Name
        };

显然,我在猜名字。但请注意:

  1. 过滤有效。
  2. SQL 要简单得多
  3. 任何地方都没有无类型的字符串。
  4. 您始终可以获得所需的数据,而无需在两个地方(Include 和其他地方)指定。
  5. 检索不需要的列不会受到带宽惩罚。
  6. EF 4 中的免费性能提升。

关键是要在 LINQ 中思考,而不是在 SQL 中或像使用旧 ORM 那样无缘无故地实现整个实体。

【讨论】:

  • 这是一个很好的答案,而且信息量很大,但它对我来说不太有效,因为我不想返回匿名对象,我需要一个 JobSeries 对象,并过滤掉工作。最终结果我找到了一个 VB.NET 示例: Dim query = From c In db.Customers _ Where c.CustomerID = 1 _ Select Customer = c, _ Orders = From o In c.Orders _ Where o.OrderDate >= # 2009 年 1 月 1 日# 我想我对 EF 的经验还不够,而且我讨厌这么简单的事情却让我花很多时间!在这个实验之后回到 Fluent NHibernate!
  • 在我看来,您正在尝试将 EF 用作 NHibernate。这永远不会奏效,因为 NHibernate 使用(有点过时,恕我直言)不同的工作方式,因为它多年来根本没有 LINQ 支持,并且在该部门仍然非常有限。您不必在这里使用匿名类型;常规 POCO 可以正常工作,但是如果您的代码完全依赖于获取实体类型,那么您实际上可以保证在任何工具中执行太多 SQL,因为通常实体上的属性比您需要的任何一个都多得多操作。
  • @Dan - 我昨天遇到了这个问题,并且能够使用 AutoMapper 解决它。因此,从上面 Craig 的代码开始,为了得到你想要的结果,你可以这样做: Mapper.DynamicMap(q).
【解决方案2】:

我早就放弃了.Include(),实现了Lazy loading for Entity Framework

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多