GroupBy в записях с учетом наибольшего значения в другом столбце - PullRequest
1 голос
/ 25 февраля 2020

Я пытаюсь обработать набор записей, сгруппировав по двум указанным c столбцам и взяв наибольший порядковый номер.

У меня есть структура таблицы следующим образом: ProductDetails

ID        CountryID          StateID       Sequence     IsProductMissing          IsProductLogicProcessed
1           1                  1                1            0                       0
2           1                  1                2            1                       0
3           1                  1                3            0                       0

4           2                  2                1            0                       0
5           2                  2                2            1                       0

6           4                  6                1            1                       0

Мой ожидаемый результат будет:

ID        CountryID          StateID       Sequence     IsProductMissing          IsProductLogicProcessed
5           2                  2                2            1                       0
6           4                  6                1            1                       0

Мне нужно отфильтровать записи, где IsProductMissing равно true и IsProductLogicProcessed равно ложно для комбинации CountryID и StateID только для самой высокой записи SequenceNumber.

Поскольку IsProductMissing is true и IsProductLogicProcessed is false на самом высоком порядковом номере для комбинации CountryID и StateID, Идентификаторы 5 и 6. фильтруются.

-

Я пробовал следующие вещи.

var takeDistinctCountryIDStateID = (await _ProductDetails.GetAll().Where(x=>x.IsProductMissing == true &&
x.IsProductLogicProcessed == false).Select(x=>new {
x.CountryID,
x.StateID
}).Distinct().Take(20)).ToListAsync());
var joinOnACtualTable = await(from p _ProductDetails.GetAll()
                             join s in takeDistinctCountryIDStateID 
                             on new {p.CountryID,p.StateID} equals new {s.CountryID,s.StateID}
                             select p).ToListAsync();
var actualOutput = from t in joinOnACtualTable 
                   group t by new { a = t.CountryID,b=t.StateID} into g
                   select g.OrderByDescending(b=>b.Sequence).FirstOrDefault();

Есть две проблемы в другом запросы

  1. Неверный набор записей: я бы получил вывод неправильно как * 1 049 *
     ID        CountryID          StateID       Sequence     IsProductMissing          IsProductLogicProcessed
        3           1                  1                3            0                       0
        5           2                  2                2            1                       0
        6           4                  6                1            1                       0

Поскольку для комбинации (CountryID, StateID) (1,1) вторая последовательность имеет IsProductMissing = 1, IsProductLogicProcessed = 0, она неправильно выбрала идентификационный номер 3 а также.

В запросе linq номер 2 окно вывода показывает, что оно выполняет объединение, перенося все записи из таблицы ProductDetails в память, что очень неэффективно.

Если бы у меня было 1 миллион записей, это в конечном итоге истекло бы.

Итак, как упростить это и получить ожидаемый результат, используя выражения Linq / lambda?

1 Ответ

0 голосов
/ 25 февраля 2020

// для вашего элемента-кандидата с x.IsProductMissing == true && x.IsProductLogicProcessed == false // проверяем, является ли это наивысшей последовательностью для StateId и CountryId, проверяя, существует ли какая-либо более высокая последовательность для этого StateId и countryId

            var yourList = (await _ProductDetails.GetAll());

            var takeDistinctCountryIDStateID = (yourList.Where(x => x.IsProductMissing == true &&
                    x.IsProductLogicProcessed == false && !yourList.Where(y=> y.StateId == x.StateId && y.CountryID == x.CountryID && y.Sequece > x.Sequence).Any()).Select(x => new {
                    x.CountryID,
                    x.StateID
                    }).Distinct().Take(20)).ToListAsync());

это может быть неэффективно для 1 миллиона записей - вы можете использовать отсортированный список и использовать методы binarySearching через функции Lambda, чтобы ускорить его

...