使用Let进行筛选

本文关键字:筛选 Let 使用 | 更新日期: 2023-09-27 18:28:16

我继承了一个带有以下tblTradeSpends表的应用程序:

ID   PromoID    Customer    LineOfBusiness     DealYear    VersionDate
1    p100       200         SCF                2013        2/23/2013
2    p101       200         SCF                2013        2/23/2013
3    p102       200         SCF                2013        2/23/2013
4    p103       200         SCF                2013        2/23/2013
5    p100       200         SCF                2013        3/23/2013
6    p101       200         SCF                2013        3/23/2013
7    p102       200         SCF                2013        3/23/2013

Customer、LineOfBusiness、DealYear和VersionDate的组合构成了交易块的"版本"概念。上面的数据描述了具有以下促销ID的两个版本:

Version 1 (Created 2/23/2013): p100, p101, p102, p103
Version 2 (Created 3/23/2013): p100, p101, p102

因此,当更新此交易块时,与PromoID p103的交易被删除。

我有一个屏幕,我想只显示一块交易的最新版本。我想出了以下方法,我认为它有效,但实际上有一个错误:

var records = from t in query
let maxversion =
            (from v in _context.tblTradeSpends
            where v.PromoID == t.PromoID
            select v.VersionDate).Max()
where t.PlanType == "Planner" &&
t.VersionDate == maxversion
select t

现在,p103交易在最新版本中被销售人员删除,但由于它拥有任何带有促销ID的交易的最长日期,因此它将被显示。

ID   PromoID    Customer    LineOfBusiness     DealYear    VersionDate
4    p103       200         SCF                2013        2/23/2013
5    p100       200         SCF                2013        3/23/2013
6    p101       200         SCF                2013        3/23/2013
7    p102       200         SCF                2013        3/23/2013

我不希望在此结果集中使用p103。如何更新我的查询,以便只显示Customer、LineOfBusiness和DealYear的唯一组合的最新VersionDate的记录?

更新

如果不太麻烦的话,在SQL中,我会按Customer#、LineOfBusiness和DealYear进行分组,确定该组的最大VersionDate,然后将该日期用于我的筛选器。我不确定在这里该怎么做。

使用Let进行筛选

类似的东西?

    var records = from t in query
    let maxversion =
            (from v in _context.tblTradeSpends
            where v.Customer == t.Customer
            && v.LineOfBusiness == t.LineOfBusiness
            && v.DealYear == t.DealYear
            select v.VersionDate).Max()
    where t.PlanType == "Planner" &&
    t.VersionDate == maxversion
    select t

好的,如果我理解正确的话,p103被删除了,因为它的VersionDate不是表中的最大值。因此,这意味着当表具有新的VersionDate s时,例如4/23/2013,所有没有此日期的记录都应该被忽略?

ID   PromoID    Customer    LineOfBusiness     DealYear    VersionDate
1    p103       200         SCF                2013        2/23/2013  // Deprecated
2    p102       200         SCF                2013        2/23/2013  // Deprecated
3    p102       200         SCF                2013        3/23/2013

听起来你只需要表的最大VersionDate,以及所有有它的记录。对吗?

var records = from t in query
    let maxversion =
        (from v in _context.tblTradeSpends
        where v.Customer == t.Customer &&
              v.LineOfBusiness == t.LineOfBusiness &&
              v.DealYear == t.DealYear
        select v.VersionDate).Max()
    where t.PlanType == "Planner" &&
    t.VersionDate == maxversion 
    select t

这适用于Linq-to对象,不确定是否与Linq2SQL/EF 一起使用

var records = (from t in _context.tblTradeSpends
       where t.PlanType == "Planner"
       group t by new { t.Customer, t.LineOfBusiness, t.DealYear } into g
       let maxVersion = g.Max(promo => promo.VersionDate)
       select g.Where(p => p.VersionDate == maxVersion)).SelectMany(s => s)

我认为问题在于,由于您在子查询中使用了t,所以每行都有一个maxversion,而不是一个用于整个查询。您需要从您想要的结果中选择最大版本。这可能有效:

var query = query.Where(t => t.PlanType == "Planner");
var records = from t in query
  let maxversion =
            (from v in query
            select v.VersionDate).Max()
  where t.VersionDate == maxversion
  select t;