【问题标题】:Joining two IQueryables加入两个 IQueryables
【发布时间】:2015-02-07 09:30:29
【问题描述】:

我的问题有点难以解释,所以请耐心等待,我会尽力解释并提供尽可能多的信息。

所以我有两张桌子:

[Table("Items")]
public class Item : BaseModel
{
  [Key]
  [Column("Id")]
  public Guid Id { get; set; }

  [Column("DescriptionId")]
  public Guid DescriptionId { get; set; }

  [ForeignKey("Id")]
  public LanguageText LanguageText { get; set; }

  [ForeignKey("DescriptionId")]
  public LanguageText DescriptionText { get; set; }
}



[Table("Shops")]
 [Serializable]
 public class Shop: BaseModel
{
    [Key]
    [Column("Id")]
    public Guid Id { get; set; }

    [Column("ItemId")]
    public Guid? ItemId{ get; set; }

    [Column("Closed")]
    public DateTime? Closed{ get; set; }

    [ForeignKey("ItemId")]
    public Item ItemModel{ get; set; }
}

我的查询

var items= itemRepository.GetAll()
                        .Include(x => x.LanguageText)
                        .Include(x => x.DescriptionText);




var querableShops = shopRepository.GetAll()
                        .Where(x =>!x.Closed.HasValue || (x.Closed.HasValue && x.Closed.Value >= Expiration))
                        .GroupJoin(items, s => s.ItemId, i => i.Id, (x, y) => x);

当我进行查询时会发生有趣的事情。当我调试 querableShops 并想要检查我的 ItemModel 时,它为空,除非我首先展开项目的结果视图。因此,我的项目不会显示在数据网格中,除非我事先在调试中手动检查项目。我认为问题在于我的项目是 IQueryable,我确实尝试将其转换为 IEnumerable,但这也没有解决我的问题。

【问题讨论】:

  • GetAll 会发生什么?存储库是否共享相同的上下文?
  • GetAll() 返回 DBSet。是的,存储库位于相同的上下文中
  • 我认为您的项目中启用了延迟加载,因此您需要急切地加载它们,因此将它们转换为 ToList() 会有所帮助。 db.itemRepository.Include(x => x.LanguageText) .Include(x => x.DescriptionText) .ToList();

标签: entity-framework ienumerable iqueryable outer-join


【解决方案1】:

尝试调用 ToList() 来枚举结果。

【讨论】:

  • 正如我在上一句中所说,我确实尝试过。
  • 我看不到任何枚举您的查询中的项目,因此如果您尝试将 ToList 与项目查询一起使用,当您将 toList 与最终查询一起使用时,您应该会得到一些东西。
  • 如果这样做,我会收到以下错误:无法创建类型为“Namespace.Item”的常量值。此上下文仅支持原始类型或枚举类型。
  • 是当您调用 list 查询此查询的时候吗? var items= itemRepository.GetAll() .Include(x => x.LanguageText) .Include(x => x.DescriptionText);
  • 是的,像这样: var items= itemRepository.GetAll() .Include(x => x.LanguageText) .Include(x => x.DescriptionText).ToList();
【解决方案2】:

这是因为(x, y) => x 您只选择了商店,而没有从查询中选择商品。 EF 总是尝试确定作为查询一部分的实体是否真的对最终结果产生影响。如果不是,它们将被忽略。在这种情况下,items 没有任何区别,因为 -

  1. 它们不会投影到结果集
  2. 联接是外联接,因此它们没有任何选择性作用。

实际上,您只查询Shops,我认为生成的 SQL 只会在此表上显示一个简单的查询。

请注意,GroupJoinInclude 不同。如果您想要商店他们的商品,您必须使用 Include 声明获取商店。这个存储库层的麻烦在于,这可能会导致责任冲突(在架构上,即不是技术上)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多