Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 19.02.15 16:26
Оценка:
BLToolkit
Собственно сабж.

Надо, чтобы работало вот это https://smehrozalam.wordpress.com/2009/12/29/linq-how-to-get-the-latest-last-record-with-a-group-by-clause/

Пытаюсь выполнить код
from p in PersonOrders
//where conditions or joins with other tables to be included here
group p by p.PersonID into grp
select grp.OrderByDescending(g=>g.OrderDate).First()

Приложение падает. Реально ли сделать то, что хочу? Или проще plain text sql писать?
Re: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 20.02.15 06:08
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>BLToolkit

SE>Собственно сабж.

SE>Надо, чтобы работало вот это https://smehrozalam.wordpress.com/2009/12/29/linq-how-to-get-the-latest-last-record-with-a-group-by-clause/


SE>Пытаюсь выполнить код

SE>
SE>from p in PersonOrders
SE>//where conditions or joins with other tables to be included here
SE>group p by p.PersonID into grp
SE>select grp.OrderByDescending(g=>g.OrderDate).First()
SE>

SE>Приложение падает. Реально ли сделать то, что хочу? Или проще plain text sql писать?

Точнее падает (без кидания exception) только во втором случае. В первом же ловлю исключение:
Additional information: 'Key' is not a member of type '<>f__AnonymousType0`2[System.Linq.IGrouping`2[System.String,DataModels.customer],System.Int32]'

Попробовал linq2db, тоже самое
Re[2]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 20.02.15 08:21
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>Здравствуйте, ShurikEv, Вы писали:


SE>>BLToolkit

SE>>Собственно сабж.

SE>>Надо, чтобы работало вот это https://smehrozalam.wordpress.com/2009/12/29/linq-how-to-get-the-latest-last-record-with-a-group-by-clause/


SE>>Пытаюсь выполнить код

SE>>
SE>>from p in PersonOrders
SE>>//where conditions or joins with other tables to be included here
SE>>group p by p.PersonID into grp
SE>>select grp.OrderByDescending(g=>g.OrderDate).First()
SE>>

SE>>Приложение падает. Реально ли сделать то, что хочу? Или проще plain text sql писать?

SE>Точнее падает (без кидания exception) только во втором случае. В первом же ловлю исключение:

SE>Additional information: 'Key' is not a member of type '<>f__AnonymousType0`2[System.Linq.IGrouping`2[System.String,DataModels.customer],System.Int32]'

SE>Попробовал linq2db, тоже самое

Проверил в EF, всё работает. Блин, почему BLT не может?
Похоже придётся текстом набирать запрос
Re[3]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 20.02.15 09:44
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>Здравствуйте, ShurikEv, Вы писали:


SE>>Здравствуйте, ShurikEv, Вы писали:


SE>>>BLToolkit

SE>>>Собственно сабж.

SE>>>Надо, чтобы работало вот это https://smehrozalam.wordpress.com/2009/12/29/linq-how-to-get-the-latest-last-record-with-a-group-by-clause/


SE>>>Пытаюсь выполнить код

SE>>>
SE>>>from p in PersonOrders
SE>>>//where conditions or joins with other tables to be included here
SE>>>group p by p.PersonID into grp
SE>>>select grp.OrderByDescending(g=>g.OrderDate).First()
SE>>>

SE>>>Приложение падает. Реально ли сделать то, что хочу? Или проще plain text sql писать?

SE>>Точнее падает (без кидания exception) только во втором случае. В первом же ловлю исключение:

SE>>Additional information: 'Key' is not a member of type '<>f__AnonymousType0`2[System.Linq.IGrouping`2[System.String,DataModels.customer],System.Int32]'

SE>>Попробовал linq2db, тоже самое

SE>Проверил в EF, всё работает. Блин, почему BLT не может?
SE>Похоже придётся текстом набирать запрос

Выкрутился
var tbl = customersDb.Customer
                    .GroupBy(c => c.PassportNumber)
                    .Select(groups => new {groups.Key, MaxId = groups.Max(g => g.Id)});

                var res = from c in customersDb.Customer
                    from t in tbl
                    where c.Id == t.MaxId
                    select new {c.FirstName, c.LastName, c.PassportNumber};

                var result = res.ToList();

Правда генерируется аж 3 селекта вместо 2х
SELECT
    [t4].[FirstName] as [FirstName1],
    [t4].[LastName] as [LastName1],
    [t4].[PassportNumber] as [PassportNumber1]
FROM
    (
        SELECT
            [t1].[customer_id] as [Id],
            [t3].[c1] as [c11],
            [t1].[customer_first_name] as [FirstName],
            [t1].[customer_last_name] as [LastName],
            [t1].[customer_passport_number] as [PassportNumber]
        FROM
            [customers] [t1],
            (
                SELECT
                    Max([t2].[customer_id]) as [c1]
                FROM
                    [customers] [t2]
                GROUP BY
                    [t2].[customer_passport_number]
            ) [t3]
    ) [t4]
WHERE
    [t4].[Id] = [t4].[c11]
Re[3]: Как получить последнюю/первую запись в группировке?
От: IT Россия linq2db.com
Дата: 23.02.15 03:14
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>Проверил в EF, всё работает. Блин, почему BLT не может?


Какой SQL генерирует EF?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Как получить последнюю/первую запись в группировке?
От: IT Россия linq2db.com
Дата: 23.02.15 03:56
Оценка:
Здравствуйте, IT, Вы писали:

IT>Какой SQL генерирует EF?


Пофиксил, но что генерирует EF всё равно интересно.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 23.02.15 15:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, ShurikEv, Вы писали:


SE>>Проверил в EF, всё работает. Блин, почему BLT не может?


IT>Какой SQL генерирует EF?

SELECT 
    [Extent2].[customer_id] AS [customer_id], 
    [Extent2].[customer_last_name] AS [customer_last_name], 
    [Extent2].[customer_first_name] AS [customer_first_name], 
    [Extent2].[customer_passport_number] AS [customer_passport_number]
    FROM   (SELECT 
        [Extent1].[customer_passport_number] AS [K1], 
        MAX([Extent1].[customer_id]) AS [A1]
        FROM [dbo].[customers] AS [Extent1]
        GROUP BY [Extent1].[customer_passport_number] ) AS [GroupBy1]
    INNER JOIN [dbo].[customers] AS [Extent2] ON (([GroupBy1].[K1] = [Extent2].[customer_passport_number]) OR (([GroupBy1].[K1] IS NULL) AND ([Extent2].[customer_passport_number] IS NULL))) AND ([Extent2].[customer_id] = [GroupBy1].[A1])

и
SELECT 
    1 AS [C1], 
    [Limit1].[customer_id] AS [customer_id], 
    [Limit1].[customer_last_name] AS [customer_last_name], 
    [Limit1].[customer_first_name] AS [customer_first_name], 
    [Limit1].[customer_passport_number] AS [customer_passport_number]
    FROM   (SELECT DISTINCT 
        [Extent1].[customer_passport_number] AS [customer_passport_number]
        FROM [dbo].[customers] AS [Extent1] ) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) [Project2].[customer_id] AS [customer_id], [Project2].[customer_first_name] AS [customer_first_name], [Project2].[customer_last_name] AS [customer_last_name], [Project2].[customer_passport_number] AS [customer_passport_number]
        FROM ( SELECT 
            [Extent2].[customer_id] AS [customer_id], 
            [Extent2].[customer_first_name] AS [customer_first_name], 
            [Extent2].[customer_last_name] AS [customer_last_name], 
            [Extent2].[customer_passport_number] AS [customer_passport_number]
            FROM [dbo].[customers] AS [Extent2]
            WHERE ([Distinct1].[customer_passport_number] = [Extent2].[customer_passport_number]) OR (([Distinct1].[customer_passport_number] IS NULL) AND ([Extent2].[customer_passport_number] IS NULL))
        )  AS [Project2]
        ORDER BY [Project2].[customer_id] DESC ) AS [Limit1]

Как-то сильно мудрено
Re[5]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 23.02.15 15:37
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, IT, Вы писали:


IT>>Какой SQL генерирует EF?


IT>Пофиксил, но что генерирует EF всё равно интересно.

А где взять обновленную сборку. В nuget её нет
Re[6]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 25.02.15 06:12
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>Здравствуйте, IT, Вы писали:


IT>>Здравствуйте, IT, Вы писали:


IT>>>Какой SQL генерирует EF?


IT>>Пофиксил, но что генерирует EF всё равно интересно.

SE>А где взять обновленную сборку. В nuget её нет
Смотрю тут ничего нет
Re[7]: Как получить последнюю/первую запись в группировке?
От: rameel https://github.com/rsdn/CodeJam
Дата: 25.02.15 15:05
Оценка:
Здравствуйте, ShurikEv, Вы писали:

SE>В nuget её нет


Уже есть, версия 1.0.7.1
... << RSDN@Home 1.2.0 alpha 5 rev. 76>>
Re[8]: Как получить последнюю/первую запись в группировке?
От: ShurikEv  
Дата: 02.03.15 07:55
Оценка:
Здравствуйте, rameel, Вы писали:

R>Здравствуйте, ShurikEv, Вы писали:


SE>>В nuget её нет


R>Уже есть, версия 1.0.7.1


Это вы про linq2db, а я про BLT
Re[5]: Как получить последнюю/первую запись в группировке?
От: seregaa Ниоткуда http://blogtani.ru
Дата: 03.03.15 21:59
Оценка:
Здравствуйте, IT, Вы писали:

IT>Пофиксил, но что генерирует EF всё равно интересно.


Писал об этой проблеме еще 2 года назад — http://rsdn.ru/forum/prj.rfd/5029507
Автор: seregaa
Дата: 13.01.13

Обновился на 1.0.7.1 но так и не заработало.

linq
var r = from row in db.Message
    group row by row.UnitId into grouped
    select grouped.OrderBy(g => g.Created).First();


Ожидаю, что выражение превратится в такой запрос:
select * from (
    select *, row_number() over (partition by UnitId order by Created) as rn from Table1)
where
    rn = 1


Раньше получал ошибку
Column 't1.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Сейчас ругнулось
Multiple queries are not allowed. Set the 'LinqToDB.Common.Configuration.Linq.AllowMultipleQuery' flag to 'true' to allow multiple queries.

После установки AllowMultipleQuery = true опять ругнулось на "Sequence is empty", а в логах зафиксирована попытка сначала выгрести из БД уникальные значения поля групировки (UnitId), а потом отдельными запросами все записи каждой группы. Что тоже неправильно, ведь запрос можно выполнить за один подход.

p.s. Я работаю с Oracle, но думаю что в этом случае поведение для оракла и mssql должно быть одинаковое — оконные функции есть и там и тут.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.