【问题标题】:Use related entity multiple times in query在查询中多次使用相关实体
【发布时间】:2015-04-26 18:24:21
【问题描述】:

我正在尝试将两个表的列表放入我制作的通用类的一个列表中。

我的问题是如何在不为每个字段调用 firstOrDefault 的情况下从相关表中获取字段,请参阅示例代码,我需要为字段价格和成本设置很长的一行,我还有更多工作要做.. .

    Dim items As IQueryable(Of ItemMain)


    Return items.Where(Function(i) i.Status > -1).Select(Function(x) New ItemViewBasic() With {.ItemID = x.ItemID,
                                                                      .Name = x.Name,
                                                                      .BarcodeNumber = x.BarcodeNumber,
                                                                      .Price = x.ItemStores.Where(Function(itemStore) itemStore.StoreNo = GlobalValues.StoreID).FirstOrDefault().Price,
                                                                      .Cost = x.ItemStores.Where(Function(itemStore) itemStore.StoreNo = GlobalValues.StoreID).FirstOrDefault().Cost})

【问题讨论】:

  • 使用提供let的查询语法。 msdn.microsoft.com/en-us/library/bb531379.aspx
  • 请将此添加为答案,以便我将其标记为已回答。谢谢。
  • 你自己解决了这个问题,我想说你会成为那个添加答案的人。在您的答案中包含您生成的代码,以便人们可以看到您是如何准确转换它的。
  • 好吧,我做到了……看来你不需要加分了……

标签: .net vb.net entity-framework linq-to-entities entity-relationship


【解决方案1】:

在从 cmets 中的 @Jeroen-Vannevel 那里得到关于使用 let 关键字的提示后,我想出了如何去做。我把它贴在这里以供将来参考..

      Return (From i In items Let itemStore = i.ItemStores.Where(Function(its) its.StoreNo = GlobalValues.StoreID And its.Status > -1).FirstOrDefault() Where i.Status > -1
            Select New ItemViewBasic With {.ItemID = i.ItemID,
                                           .Name = i.Name,
                                           .Cost = itemStore.Cost,
                                           .BarcodeNumber = i.BarcodeNumber,
                                           .OnHand = itemStore.OnHand,
                                           .Department = itemStore.DepartmentID,
                                           .Price = itemStore.Price,
                                           .ModalNumber = i.ModalNumber})

【讨论】:

    【解决方案2】:

    我将使用的方法(在 C# 中)是首先为相关商店的 ItemStore 记录生成查询,例如

    var itemStores = myDbContext.ItemStores.Where(i => i.StoreNo = GlobalValues.StoreID);
    

    然后将它加入你已经拥有的项目:

    return items.Join(itemStores, i => ItemId, is => is.ItemID, (i, is) => new ItemViewBasic {etc });
    

    【讨论】:

    • 那是两次往返......我试图避免这种情况。
    • 不一定。第一个查询只会在需要时执行(除非您通过在末尾添加 .ToList() 来强制进行早期评估)。您可能会发现它在幕后针对单个 SQL 查询进行了优化。我不确定它会走哪条路。
    • 我对这种方法有疑问......因为我使用的是 devexpress 脚手架,所以此时我无法直接访问 dbContext。如果我创建上下文的新实例,我会收到一条错误消息,指出我无法与上下文相关...
    • 可惜。如果没有 dbContext,则看不到优雅的方法。我唯一能想到的就是定义一个 ItemViewBasic2 对象,它上面有 StoreID 以及你想要的。无论 StoreID 是什么,都选择所有这些,然后使用后续的 Where 子句进行过滤以仅获取您想要的那些。最后选择您的 ItemViewBasic 对象。丑陋,但它仍然只是对数据库的一次访问,并且可能会导致完美的最佳 SQL。
    • 感谢您的帮助。我找到了如何使用 let 关键字,这对我有用...
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多