Фильтрация с помощью Let

Я унаследовал приложение со следующей таблицей 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 составляет понятие «Версия» для блока сделок. Приведенные выше данные описывают две версии со следующими промо-идентификаторами:

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   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 в этом наборе результатов. Как я могу обновить свой запрос, чтобы отображались только записи с последней версией VersionDate для уникальной комбинации Customer, LineOfBusiness и DealYear?

ОБНОВЛЕНИЕ

Если это не сильно мутит воду, в SQL я бы сгруппировал по Customer #, LineOfBusiness и DealYear, определил максимальную VersionDate для группы, а затем использовал эту дату для своего фильтра. Я не уверен, как сделать то же самое здесь.


person Mister Epic    schedule 19.08.2013    source источник
comment
Имеет ли эта строка p103 значение, отличное от других результатов? И вы хотите удалить только строку p103 в наборе результатов, верно?   -  person 123 456 789 0    schedule 19.08.2013
comment
Я хочу удалить любую запись, в которой дата версии не равна максимальной дате версии любой другой записи с тем же номером клиента, LineOfBusiness и DealYear. Имеет ли это смысл?   -  person Mister Epic    schedule 19.08.2013
comment
Да, но ваша проблема сейчас в том, что p103 имеет версию VersionDate, которая является максимальной версией, поэтому она включается в список. А что такое MaxVersion здесь, это 23.03.2013?   -  person 123 456 789 0    schedule 19.08.2013
comment
@LeoLorenzoLuis Максимальная дата версии для предоставленного мной образца — 23 марта 2013 г., так как это последняя VersionDate уникальная комбинация записей с Customer# = 200, LineOfBusiness = SCF и DealYear = 2013.   -  person Mister Epic    schedule 19.08.2013
comment
@ChrisHardie Что касается вашего обновления, если вы получите максимальную дату для каждой группы, вы все равно выберете p103.   -  person Artless    schedule 19.08.2013
comment
@Trickery Могу ли я? Максимальной датой версии для группы будет 23 марта 2013 г. Дата версии p103 — 23 февраля 2013 г. Разве этого недостаточно, чтобы отфильтровать ее?   -  person Mister Epic    schedule 19.08.2013
comment
@ChrisHardie Ммм .. Вам нужна максимальная дата для каждой уникальной комбинации Customer, LineOfBusiness и DealYear. А потом вы хотите, чтобы все записи в этой группе были с максимальной датой? Я обновил свой ответ, может быть, на этот раз я правильно понял.   -  person Artless    schedule 19.08.2013


Ответы (4)


Что-то вроде этого?

    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
person stevepkr84    schedule 19.08.2013

Ладно, если я правильно понял, p103 убран, потому что его VersionDate не является максимальным в таблице. Так это означает, что когда в таблице есть новые VersionDate, например, 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
person Artless    schedule 19.08.2013
comment
Нет, мне не нужна максимальная версия VersionDate таблицы, так как у нас есть тысячи блоков сделок, мне нужна максимальная версия VersionDate для каждой уникальной комбинации Customer#, LineOfBusiness и DealYear. Предоставленные мной образцы данных были бесконечно малым подмножеством, которое я использовал, пытаясь прояснить свой вопрос. - person Mister Epic; 19.08.2013
comment
Давай, но другой парень только что опередил тебя с таким же вопросом. Ваше здоровье! - person Mister Epic; 19.08.2013

Это работает для Linq для объектов, не уверен в использовании с 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)
person PHeiberg    schedule 19.08.2013

Я думаю, проблема в том, что, поскольку вы используете 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;
person Tim S.    schedule 19.08.2013
comment
Разве это не даст мне максимальную дату версии для таблицы? Эта дата не применима к большинству блоков сделок. Чем больше я думаю об этом, тем больше я считаю, что мне нужно сгруппировать по номеру клиента, линии бизнеса и году сделки. - person Mister Epic; 19.08.2013