【问题标题】:C# Entity Framework 4.1 Lambda Include - only select specific included valuesC# Entity Framework 4.1 Lambda Include - 只选择特定的包含值
【发布时间】:2011-09-19 03:46:15
【问题描述】:

我正在 EF4.1 上进行 lambda 选择,包括我当前语句中的另一个相关 DBSet。

 return dbEntity.GameTypes.Include(a => a.Draws)
                           .Where(d => d.IsActive == true )
                           .ToList();

我有两个课程:

//simplified versions of the classes
public class GameType
{
 public Nullable<bool> IsActive { get; set; }
 public virtual ICollection<Draw> Draws { get; set; }
}

public class Draw
{
 public int DrawID { get; set; }
 public int GameTypeID { get; set; }
 public System.DateTime DrawDate { get; set; }
} 

但我只想要每个 GameType 的下一个即将到来的抽奖。基本上我想做类似的事情

 return dbEntity.GameTypes.Include(a => a.Draws.Where(aw => aw.DrawDate > System.DateTime.Now)
                                               .OrderBy(ao => ao.DrawDate)
                                               .First())
                           .Where(d => d.IsActive == true )
                           .ToList();

但它给了我:

包含路径表达式必须引用在类型上定义的导航属性。对引用导航属性使用虚线路径,对集合导航属性使用 Select 运算符。

这样的事情可能吗,还是我需要在之后过滤结果?然后我还想按最新的 Draw.DrawDate 排序总结果。如果有人能告诉我正确的方法,我将不胜感激。

【问题讨论】:

  • 您只能在导航属性上执行 .Include。 Peter Hancock 的查询很好,但您不需要在该查询中执行 Include。
  • 我认为这取决于是否启用延迟加载和代理创建-如果启用,则不需要包含-如果没有,则包含
  • 从 EntityFramework 4.1 你必须使用 System.Data.Entity: using System.Data.Entity ... MyDBContext.MySet.Include(o => o.MyAssociation)

标签: c# lambda include entity-framework-4.1


【解决方案1】:

我觉得……

    from g in dbEntity.GameTypes.Include("Draws")
   where g.IsActive
     let d = g.Draws.Where(o => o.DrawDate > System.DateTime.Now)
                    .OrderBy(o => o.DrawDate)
                    .Take(1)       // Needs to stay a collection
  select new GameType {IsActive = g.IsActive, Draws = d}

未经测试 - 但它可能会让你走上正确的道路......

【讨论】:

  • 我认为这仍然会导致所有关联的Draws 失效。
  • 我不这么认为 - DrawDate 正在过滤 Draws > 现在,然后在 Take(1) 之前排序
  • 你不需要这样做。在第一行包含这里
  • 这取决于上下文是否开启了延迟加载和代理创建。鉴于原始请求包含包含,我建议关闭代理创建和延迟加载 => 需要包含。
  • 谢谢彼得。它确实给出了一些错误,但决定不花太多时间玩它。就性能和我需要它做的事情而言,我认为最好的办法是创建一个 SProc 和一个相关的复杂类型。
【解决方案2】:

来自 MSDN 的 DbExtensions.Include()

路径表达式必须组成 简单的属性访问表达式 连同按顺序调用 Select 在之后撰写其他包含 包括一个集合属性。

所以我认为不允许使用Where()。我不确定您是否可以对Include() 进行任何过滤。

【讨论】:

    【解决方案3】:

    我从来没有成功地找到像您想要的那样过滤孩子的方法。为了减少从数据库中检索的数据量,我通常只检索父对象,然后遍历它们,只获取我想要的子对象并将它们“附加”到父对象。不过,这并不是一成不变的规则,它有点取决于每个父母有多少孩子,以及我可能想要保留的孩子比例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多