Linq2db что можна бы было улучшить
От: Danchik Украина  
Дата: 20.03.15 13:13
Оценка:
Привет Игорь,

Поигрался над прототипом для клиента, и переписал пару выборок с хранимок на Linq2db (SQL Server, Azure SQL).
Сиквел генерится просто чудестно, но есть некоторые вещи которых не хватает или я не нашел

  1. Хотелось бы иметь возможнось вызывать всторенную фунцию ISNULL(SomeField, 0)
  2. Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=
  3. Параметры дублируются, вот что получилось из всего двух переменных start и end
    DECLARE @start1 DateTime2
    SET     @start1 = '2012-03-20'
    DECLARE @end1 DateTime2
    SET     @end1 = '2015-03-20'
    DECLARE @start2 DateTime2
    SET     @start2 = '2012-03-20'
    DECLARE @end2 DateTime2
    SET     @end2 = '2015-03-20'
    DECLARE @end3 DateTime2
    SET     @end3 = '2015-03-20'
    
    SELECT
        [s].[AccountName],
        Sum(IIF([c].[RoutingCategory] = N'Resolved', [c].[PieceCount], 0)) as [c1],
        Sum(IIF([c].[RoutingCategory] = N'Resolved', 0, [c].[PieceCount])) as [c2]
    FROM
        [dbo].[Counts] [c]
            INNER JOIN [dbo].[Sessions] [s] ON [c].[Application] = [s].[Application] AND [c].[JobSessionID] = [s].[JobSessionID]
    WHERE
        NOT ([s].[AccountName] IS NULL OR Len([s].[AccountName]) = 0) AND
        NOT ([s].[DepartmentName] IS NULL OR Len([s].[DepartmentName]) = 0) AND
        NOT ([s].[MachineID] IS NULL OR Len([s].[MachineID]) = 0) AND
        ([s].[SessionStart] >= @start1 AND [s].[SessionStart] <= @end1 OR [s].[SessionStop] >= @start2 AND [s].[SessionStop] <= @end2) AND
        [s].[SessionStart] <= @end3
    GROUP BY
        [s].[AccountName]
Уже как то говорил об этом, можна например при генерации держать список параметров и если название, тип и значение совпадают то переиспользовать.
Re: Linq2db что можна бы было улучшить
От: IT Россия linq2db.com
Дата: 20.03.15 14:15
Оценка:
Здравствуйте, Danchik, Вы писали:

D>
  • Хотелось бы иметь возможнось вызывать всторенную фунцию ISNULL(SomeField, 0)

    Это делается с помощью оператора ??.

    D>
  • Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=

    Обсуждалось тут http://rsdn.ru/forum/prj.rfd/5371102.hot
    Автор:
    Дата: 22.11.13


    D>
  • Параметры дублируются, вот что получилось из всего двух переменных start и end
    D>Уже как то говорил об этом, можна например при генерации держать список параметров и если название, тип и значение совпадают то переиспользовать.

    Генерируемый SQL кешируется. Соответственно совпадающие значения могут не совпадать при следующем запросе. Хотя, в принципе, это дело можно немного улучшить.
  • Если нам не помогут, то мы тоже никого не пощадим.
    Re[2]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 20.03.15 14:42
    Оценка:
    Здравствуйте, IT, Вы писали:

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


    D>>
  • Хотелось бы иметь возможнось вызывать всторенную фунцию ISNULL(SomeField, 0)

    IT>Это делается с помощью оператора ??.


    Посыпаю голову пеплом, но все равно, это не спасет при LEFT JOIN.
    ?? не поставишь на int поле.

    D>>
  • Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=

    IT>Обсуждалось тут http://rsdn.ru/forum/prj.rfd/5371102.hot
    Автор:
    Дата: 22.11.13


    Почему бы сразу не встроить?

    D>>
  • Параметры дублируются, вот что получилось из всего двух переменных start и end
    D>>Уже как то говорил об этом, можна например при генерации держать список параметров и если название, тип и значение совпадают то переиспользовать.

    IT>Генерируемый SQL кешируется. Соответственно совпадающие значения могут не совпадать при следующем запросе. Хотя, в принципе, это дело можно немного улучшить.


    Приблизительно понял о чем речь и техническую загвоздку, но глаза все равно режет
  • Re[3]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 20.03.15 15:16
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Посыпаю голову пеплом, но все равно, это не спасет при LEFT JOIN.

    D>?? не поставишь на int поле.

    Можно преобразовать к int?
    Хотя согласен, имеет смысл добавить такую функцию. Кстати, это несложно сделать самостоятельно.

    D>>>
  • Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=
    IT>>Обсуждалось тут http://rsdn.ru/forum/prj.rfd/5371102.hot
    Автор:
    Дата: 22.11.13

    D>Почему бы сразу не встроить?

    Там был задан вопрос о сигнатуре функции.

    D>Приблизительно понял о чем речь и техническую загвоздку, но глаза все равно режет


    Я надумал серьёзный рефакторинг linq провайдера, попробую заодно и решить этот вопрос.
  • Если нам не помогут, то мы тоже никого не пощадим.
    Re[4]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 20.03.15 16:23
    Оценка:
    Здравствуйте, IT, Вы писали:

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


    D>>Посыпаю голову пеплом, но все равно, это не спасет при LEFT JOIN.

    D>>?? не поставишь на int поле.

    IT>Можно преобразовать к int?

    IT>Хотя согласен, имеет смысл добавить такую функцию. Кстати, это несложно сделать самостоятельно.

            [Sql.Expression("SqlServer", "ISNULL({0}, {1})", ServerSideOnly = true)]
            public static T IsNull<T>(T? value, T defaultValue)
                where T : struct 
            {
                throw new NotImplementedException();
            }
    
            [Sql.Expression("SqlServer", "ISNULL({0}, {1})", ServerSideOnly = true)]
            public static T IsNull<T>(T value, T defaultValue)
            {
                throw new NotImplementedException();
            }


    D>>>>
  • Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=
    IT>>>Обсуждалось тут http://rsdn.ru/forum/prj.rfd/5371102.hot
    Автор:
    Дата: 22.11.13

    D>>Почему бы сразу не встроить?

    IT>Там был задан вопрос о сигнатуре функции.


            [Sql.Expression("SqlServer", "{0} BETWEEN {1} AND {2}", ServerSideOnly = false, Precedence = 1)]
            public static bool Between<T>(T? value, T? low, T? high)
                where T : struct, IComparable
            {
                if (!value.HasValue || !low.HasValue || !high.HasValue)
                {
                    return false;
                }
    
                if (value.Value.CompareTo(low.Value) < 0)
                    return false;
    
                if (value.Value.CompareTo(high.Value) > 0)
                    return false;
    
                return true;
            }
    
            [Sql.Expression("SqlServer", "{0} BETWEEN {1} AND {2}", ServerSideOnly = false, Precedence = 1)]
            public static bool Between<T>(T? value, T low, T high)
                where T : struct, IComparable
            {
                if (!value.HasValue)
                {
                    return false;
                }
    
                if (value.Value.CompareTo(low) < 0)
                    return false;
    
                if (value.Value.CompareTo(high) > 0)
                    return false;
    
                return true;
            }


    D>>Приблизительно понял о чем речь и техническую загвоздку, но глаза все равно режет


    IT>Я надумал серьёзный рефакторинг linq провайдера, попробую заодно и решить этот вопрос.


    Совершенству нет пределов Это в который то раз?
  • Re: Linq2db что можна бы было улучшить
    От: AK107  
    Дата: 21.03.15 09:18
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Не нашел возможности сделать BETWEEN, оно бы было как то нативней чем >= <=


    дарю:
            [Sql.Expression("{0} BETWEEN {1} AND {2}", ServerSideOnly = true)]
            public static bool Between<T>(T x, T low, T high) where T : IComparable<T>
            {
                // x >= low && x <= high
                return x.CompareTo(low) >= 0 && x.CompareTo(high) <= 0;
            }


    ИМХО в таком виде наиболее удобоваримо и можно добавить в linq2db
    Отредактировано 15.05.2015 14:17 AK107 . Предыдущая версия .
    Re[5]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 21.03.15 20:07
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Совершенству нет пределов Это в который то раз?


    На самом деле раньше это всё было допиливание существующего кода. Но накопился рад проблем, которые с текущим дизайном решить практически невозможно. Нужно полностью переписывать linq provider.

    Не хотелось бы чтобы из-за внутренних проблем дизайна продукт начал тормозиться в развитии или вообще сдулся и тихо помер, как это практически произошло с Немерле.
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[6]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 23.03.15 11:26
    Оценка:
    Здравствуйте, IT, Вы писали:

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


    D>>Совершенству нет пределов Это в который то раз?


    IT>На самом деле раньше это всё было допиливание существующего кода. Но накопился рад проблем, которые с текущим дизайном решить практически невозможно. Нужно полностью переписывать linq provider.


    IT>Не хотелось бы чтобы из-за внутренних проблем дизайна продукт начал тормозиться в развитии или вообще сдулся и тихо помер, как это практически произошло с Немерле.


    Ну вот, хотелось бы обратить твое внимание на EF7, как у них сейчас организована загрузка Include — отдельные запросы наконец то посылают, но SQL опять же оставляет желать лучшего.
    Re[7]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 23.03.15 15:06
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Ну вот, хотелось бы обратить твое внимание на EF7, как у них сейчас организована загрузка Include — отдельные запросы наконец то посылают, но SQL опять же оставляет желать лучшего.


    В смысле отдельные запросы?
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[8]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 23.03.15 15:34
    Оценка:
    Здравствуйте, IT, Вы писали:

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


    D>>Ну вот, хотелось бы обратить твое внимание на EF7, как у них сейчас организована загрузка Include — отдельные запросы наконец то посылают, но SQL опять же оставляет желать лучшего.


    IT>В смысле отдельные запросы?


    Посмотри на тесты

    https://github.com/aspnet/EntityFramework/blob/db70fd41a2781d682a2396af1012adda2785c37f/test/EntityFramework.SqlServer.FunctionalTests/IncludeSqlServerTest.cs

    Они в суб запросы начинают включать главный как фильтр и накладывают на него DISTINCT
    Re[9]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 23.03.15 15:49
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Они в суб запросы начинают включать главный как фильтр и накладывают на него DISTINCT


    DISTINCT — это сурово. даже на ПК не проверяют?
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[10]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 23.03.15 18:30
    Оценка:
    Здравствуйте, IT, Вы писали:

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


    D>>Они в суб запросы начинают включать главный как фильтр и накладывают на него DISTINCT


    IT>DISTINCT — это сурово. даже на ПК не проверяют?


    Неа )) На тебя вся надежда
    Re[7]: Linq2db что можна бы было улучшить
    От: Слава  
    Дата: 23.03.15 19:39
    Оценка:
    Здравствуйте, Danchik, Вы писали:

    D>Ну вот, хотелось бы обратить твое внимание на EF7, как у них сейчас организована загрузка Include — отдельные запросы наконец то посылают, но SQL опять же оставляет желать лучшего.


    А зачем это надо — отдельные запросы? Количество roundtrip до базы увеличивается, и возможно будет быстрее одним запросом получить кучу повторов, а затем извлечь из них сущности, чем делать отдельные запросы.
    Re[8]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 23.03.15 23:35
    Оценка: +1
    Здравствуйте, Слава, Вы писали:

    С>А зачем это надо — отдельные запросы? Количество roundtrip до базы увеличивается, и возможно будет быстрее одним запросом получить кучу повторов, а затем извлечь из них сущности, чем делать отдельные запросы.


    1. Серьёзно усложняется план запроса.
    2. В разы увеличивается ширина запроса.
    3. В разы увеличивается количество выгребаемых данных.

    Одним запросом имеет смысл выгребать только связи один-к-одному.
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[9]: Linq2db что можна бы было улучшить
    От: Слава  
    Дата: 27.03.15 20:39
    Оценка:
    Здравствуйте, IT, Вы писали:

    IT>Одним запросом имеет смысл выгребать только связи один-к-одному.


    А есть ли какая-то возможность "прогреть кэш" linq2db? Я заметил, что при первом выполнении любого запроса, проходит немалое время, затем он выполняется моментально. Есть некоторое количество запросов, на которые, в зависимости от условий, накладываются ограничения where. То есть, кэшировать придется все комбинации фильтров. Можно ли как-то указать linq2db — "откомпилируй запрос, закээшируй, но не выполняй"?
    Re[10]: Linq2db что можна бы было улучшить
    От: Danchik Украина  
    Дата: 28.03.15 10:47
    Оценка:
    Здравствуйте, Слава, Вы писали:

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


    IT>>Одним запросом имеет смысл выгребать только связи один-к-одному.


    С>А есть ли какая-то возможность "прогреть кэш" linq2db? Я заметил, что при первом выполнении любого запроса, проходит немалое время, затем он выполняется моментально. Есть некоторое количество запросов, на которые, в зависимости от условий, накладываются ограничения where. То есть, кэшировать придется все комбинации фильтров. Можно ли как-то указать linq2db — "откомпилируй запрос, закээшируй, но не выполняй"?


    Я не уверен, надо на код смотреть, но если попробовать сделать для IQueryable ToString то запрос будет закеширован
    Re[10]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 28.03.15 13:54
    Оценка:
    Здравствуйте, Слава, Вы писали:

    С>А есть ли какая-то возможность "прогреть кэш" linq2db? Я заметил, что при первом выполнении любого запроса, проходит немалое время, затем он выполняется моментально. Есть некоторое количество запросов, на которые, в зависимости от условий, накладываются ограничения where. То есть, кэшировать придется все комбинации фильтров. Можно ли как-то указать linq2db — "откомпилируй запрос, закээшируй, но не выполняй"?


    Есть CompiledQuery, но там тоже запрос кешируется только в момент первого выполнения, т.к. нужен реальный DataContext от которого зависит генерация SQL.
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[11]: Linq2db что можна бы было улучшить
    От: IT Россия linq2db.com
    Дата: 28.03.15 13:58
    Оценка:
    Здравствуйте, IT, Вы писали:

    IT>Есть CompiledQuery, но там тоже запрос кешируется только в момент первого выполнения, т.к. нужен реальный DataContext от которого зависит генерация SQL.


    Хотя для зависимых от условий запросов это не подойдёт.
    Если нам не помогут, то мы тоже никого не пощадим.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.