Re[28]: Entity Framework за! и против!
От: artelk  
Дата: 09.07.14 15:21
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

IT>>Ага, и как ты решил проблему верификации такого SQL?

AP>Последовательно описано в разделах 2, 3, 4, 5. И далее в разделах 7, 8 и 9.1.

Ты IL анализируешь, проверяя все if-ы во всех комбинациях зайдет/не зайдет?
Re[28]: Entity Framework за! и против!
От: artelk  
Дата: 09.07.14 15:46
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

IT>>Ага, и как ты решил проблему верификации такого SQL?

AP>Последовательно описано в разделах 2, 3, 4, 5. И далее в разделах 7, 8 и 9.1.

Еще вопрос:
Используя LINQ можно сделать, например, такой метод:

IQueryable<My> ApplyFilter(IQueryable<My> items, ...)
{
   if(foo)
     items = items.Where(...);
   if(bar)
     items = items.OrderBy(...);
   if(baz)
     items = items.Take(10);
   return items;
}


и поместить его куданить в presentation layer. Исходный IQueryable<My> приходит откуда-нибудь из низлежащих слоев.

Как с твоим подходом сделать что-то подобное?
Будет что-то такое:
StringBuilder ApplyFilter(StringBuilder items, ...)

?

Например, "Take(10)" — это ж нужно вставлять "TOP 10" в середину уже добавленной строки в StringBuilder. Как оно потом будет статически верифицироваться?
Re[29]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 09.07.14 18:10
Оценка:
A>Ты IL анализируешь, проверяя все if-ы во всех комбинациях зайдет/не зайдет?
Нет, IL код используется только для поиска методов для тестирования, см. раздел "4. Автоматический поиск методов для тестирования".
Re[29]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 09.07.14 18:12
Оценка:
A>Как с твоим подходом сделать что-то подобное?
        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
        {
            return new {items, ...}.QFragment(@"
@if(foo) {
    @:SELECT * FROM (@items(null)) _ WHERE ...
}
@if(bar) {
    @:SELECT * FROM (@items(null)) _ ORDER BY ...
}
@if(baz) {
    @:SELECT TOP 10 * FROM (@items(null)) _
}");
        }



A>Как оно потом будет статически верифицироваться?

Тестируются запросы, в которых вызывается ApplyFilter:
            var xxx = Query<Xxx>.New(new {...}, @"
...
@Foo.ApplyFilter(@<text>SELECT * FROM zzz</text>, ...)
...").List();
Re[30]: Entity Framework за! и против!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.07.14 18:36
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

A>>Как с твоим подходом сделать что-то подобное?

AP>
AP>        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
AP>        {
AP>            return new {items, ...}.QFragment(@"
AP>@if(foo) {
AP>    @:SELECT * FROM (@items(null)) _ WHERE ...
AP>}
AP>@if(bar) {
AP>    @:SELECT * FROM (@items(null)) _ ORDER BY ...
AP>}
AP>@if(baz) {
AP>    @:SELECT TOP 10 * FROM (@items(null)) _
AP>}");
AP>        }
AP>


Это не эквивалентный код Что будет если foo, bar и baz одновременно true? А сверху если сверху еще наложен .Select, который пушит проекции в подзапросы. То твой генератор начинает нервно курить в сторонке.

В этом и есть слабость твоего подхода — как не автоматизируй склейку строк, она все равно останется склейкой строк.
Re[28]: Entity Framework за! и против!
От: IT Россия linq2db.com
Дата: 09.07.14 18:59
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

IT>>Ага, и как ты решил проблему верификации такого SQL?

AP>Последовательно описано в разделах 2, 3, 4, 5. И далее в разделах 7, 8 и 9.1.

Всё так сложно? А в двух словах идую описать?
Если нам не помогут, то мы тоже никого не пощадим.
Re[31]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 09.07.14 19:06
Оценка:
G>Это не эквивалентный код Что будет если foo, bar и baz одновременно true?
Да, я невнимательно прочитал исходный код, эквивалентный вот такой код:
        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
        {
            return new {items, ...}.QFragment(@"
SELECT @if(baz) {<text>TOP 10</text>} *
FROM    (@items) _
@if(foo) {
@:WHERE   ...
}
@if(bar) {
@:ORDER BY ...
}");
        }



G>А сверху если сверху еще наложен .Select, который пушит проекции в подзапросы.

Давай примеры.

G>То твой генератор начинает нервно курить в сторонке.

Если только в твоем воображении.

G>В этом и есть слабость твоего подхода — как не автоматизируй склейку строк, она все равно останется склейкой строк.

Склейка строк это сила!!!
Re[29]: Entity Framework за! и против!
От: Ночной Смотрящий Россия  
Дата: 09.07.14 19:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Всё так сложно? А в двух словах идую описать?


http://research.microsoft.com/en-us/projects/pex/
Re[29]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 09.07.14 19:35
Оценка:
IT>Всё так сложно? А в двух словах идую описать?
Там как раз последовательно, естественно и просто написано.

В двух словах так.
Был такой old-school-ый подход выделять DAL и покрывать его тестами. Писать такие тесты довольно рутинное занятие. А рутинные, однообразные операции надо отделять и поручать машине. Вот я это и сделал.
Фрагмент кода, который формирует запрос, записываем как функцию от параметров определенных типов. Тестовые значения для параметров определяем по типу и подставляем их. И честно входим в тестовый рантайм. Обычно типы это: bool, enum и вариации на тему double dispatch: Option, Choice и т.д.
Re[32]: Entity Framework за! и против!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.07.14 21:11
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

G>>Это не эквивалентный код Что будет если foo, bar и baz одновременно true?

AP>Да, я невнимательно прочитал исходный код, эквивалентный вот такой код:
AP>
AP>        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
AP>        {
AP>            return new {items, ...}.QFragment(@"
AP>SELECT @if(baz) {<text>TOP 10</text>} *
AP>FROM    (@items) _
AP>@if(foo) {
AP>@:WHERE   ...
AP>}
AP>@if(bar) {
AP>@:ORDER BY ...
AP>}");
AP>        }
AP>


А если будет два условия на where, то станет совершенно нечтиаемо.


G>>А сверху если сверху еще наложен .Select, который пушит проекции в подзапросы.

AP>Давай примеры.

Дери результат функции ApplyFilter и сделай .Select
Даже если в подзапросе группировка, которую sql сам не соптимизирует.


G>>То твой генератор начинает нервно курить в сторонке.

AP>Если только в твоем воображении.
Сделай .select и посмотри сгененированный запрос.

G>>В этом и есть слабость твоего подхода — как не автоматизируй склейку строк, она все равно останется склейкой строк.

AP>Склейка строк это сила!!!
Была, до появления linq.
Re[33]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 10.07.14 08:41
Оценка: :)
G>А если будет два условия на where, то станет совершенно нечтиаемо.
Ошибаешься:
        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
        {
            return new {items, ...}.QFragment(@"
SELECT @if(baz) {<text>TOP 10</text>} *
FROM    (@items) _
WHERE    1 = 1 /*1 = 0*/
@if(foo) {
    @:AND/*OR*/ ...
}
@if(foo2) {
    @:AND/*OR*/ ...
}
@if(bar) {
@:ORDER BY ...
}");
        }

А вот для LINQ простейшая замена AND на OR приводит к тому, что запрос надо записывать совершенно по другому. Видим, что, если запрос не надо строить, то посредством компилятора LINQ предлагает краткий синтаксис "cond1 || cond2". Если же запрос надо строить, то компилятор нам уже не поможет, и остается лепить DSL средствами C#. Как пишет сам Anders Hejlsberg LINQ не разрабатывался для динамического построения запросов.

А поскольку команда Хейлсберга уже давно отошла от вопросов взаимодействия с реляционными СУБД, то изменений ждать не приходится.

G>Дери результат функции ApplyFilter и сделай .Select

В чем проблема?
            var xxx = Query<Xxx>.New(new {...}, @"
SELECT *
FROM   (@Foo.ApplyFilter(...)) _").List();


G>Даже если в подзапросе группировка, которую sql сам не соптимизирует.

Proof link в студию или ты опять сочиняешь.

В СУБД движок, который перезаписывает запрос и генерирует план его выполнения, гораздо круче любого LINQ провайдера. И СУБД честно отводит на это ощутимое время, а потом использует кэш. Тут важно то, что ключом в кэше является сама строка запроса. А у LINQ провайдера ключа подходящего нет.

Кстати, то, что СУБД не оптимизирует вот такое "... = @p1 OR @p1 IS NULL" связанно именно с кэшем планов. Либо надо бегать по дереву и тогда теряем в производительности кэша, либо отдать это на откуп пользователю, пусть он генерирует разные тексты для запросов, которые будут разными ключами в кэше.

G>Сделай .select и посмотри сгененированный запрос.

Посмотрел. Всё в порядке.

AP>>Склейка строк это сила!!!

G>Была, до появления linq.
И такой остается, поскольку человек видит текст, а не деревья выражений. Как пишется код? Реализуется некоторый функционал F1. Потом реализуется еще F2...FN. У F1...FN наблюдаются общие фрагменты кода, т.е. текста. Для "Don't repeat yourself" эти фрагменты надо выделить и поставить их вызовы в нескольких местах. "Don't repeat" это значит не повторять фрагменты текста. Нарезка текста на фрагменты самая естественная схема декомпозиции кода. C# предлагает такую декомпозицию для кода, который компилируется непосредственно в IL для исполнения, и не предлагает такой декомпозиции для IQueryable, выражения для которого компилируются в структуры данных для генерации SQL строк.
Re[34]: Entity Framework за! и против!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.07.14 15:43
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

G>>А если будет два условия на where, то станет совершенно нечтиаемо.

AP>Ошибаешься:
AP>
AP>        public static QFragment ApplyFilter(Func<object, QFragment> items, ...)
AP>        {
AP>            return new {items, ...}.QFragment(@"
AP>SELECT @if(baz) {<text>TOP 10</text>} *
AP>FROM    (@items) _
AP>WHERE    1 = 1 /*1 = 0*/
AP>@if(foo) {
AP>    @:AND/*OR*/ ...
AP>}
AP>@if(foo2) {
AP>    @:AND/*OR*/ ...
AP>}
AP>@if(bar) {
AP>@:ORDER BY ...
AP>}");
AP>        }
AP>

Спасибо ты подтвердил мои слова


G>>Дери результат функции ApplyFilter и сделай .Select

AP>В чем проблема?
AP>
AP>            var xxx = Query<Xxx>.New(new {...}, @"
AP>SELECT *
AP>FROM   (@Foo.ApplyFilter(...)) _").List();
AP>

Не понял, как проекция пропушится во все подзапросы?

G>>Даже если в подзапросе группировка, которую sql сам не соптимизирует.

AP>Proof link в студию или ты опять сочиняешь.
Так попробуй сам сделать.

AP>В СУБД движок, который перезаписывает запрос и генерирует план его выполнения, гораздо круче любого LINQ провайдера. И СУБД честно отводит на это ощутимое время, а потом использует кэш. Тут важно то, что ключом в кэше является сама строка запроса. А у LINQ провайдера ключа подходящего нет.

При чем тут это?

AP>Кстати, то, что СУБД не оптимизирует вот такое "... = @p1 OR @p1 IS NULL" связанно именно с кэшем планов. Либо надо бегать по дереву и тогда теряем в производительности кэша, либо отдать это на откуп пользователю, пусть он генерирует разные тексты для запросов, которые будут разными ключами в кэше.

Да, и linq тут спасает. Хоть и "ключа поодходящего нет" (с)

G>>Сделай .select и посмотри сгененированный запрос.

AP>Посмотрел. Всё в порядке.
Именно, и проекции попапил в том числе в подзапросы. Как склейкой строк такое повторить?

AP>>>Склейка строк это сила!!!

G>>Была, до появления linq.
AP>И такой остается, поскольку человек видит текст, а не деревья выражений. Как пишется код? Реализуется некоторый функционал F1. Потом реализуется еще F2...FN. У F1...FN наблюдаются общие фрагменты кода, т.е. текста. Для "Don't repeat yourself" эти фрагменты надо выделить и поставить их вызовы в нескольких местах. "Don't repeat" это значит не повторять фрагменты текста. Нарезка текста на фрагменты самая естественная схема декомпозиции кода. C# предлагает такую декомпозицию для кода, который компилируется непосредственно в IL для исполнения, и не предлагает такой декомпозиции для IQueryable, выражения для которого компилируются в структуры данных для генерации SQL строк.
Ты чего курил? В этой теме уже раз 100 приводили декомпозицию IQueryable, хоть комбинаторами (в том числе обобщенными), хоть руками деревья выражений пиши, хоть dlinq (который используется в новых веб-формах для фильтров и сортировок).
Re[35]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 10.07.14 16:24
Оценка:
G>Не понял, как проекция пропушится во все подзапросы?
Чего? Нормально условие задачи сформулировать можешь?

G>>>Даже если в подзапросе группировка, которую sql сам не соптимизирует.

AP>>Proof link в студию или ты опять сочиняешь.
G>Так попробуй сам сделать.
Как же я сделаю то, чего нет? Короче, слив засчитан.

AP>>В СУБД движок, который перезаписывает запрос и генерирует план его выполнения, гораздо круче любого LINQ провайдера. И СУБД честно отводит на это ощутимое время, а потом использует кэш. Тут важно то, что ключом в кэше является сама строка запроса. А у LINQ провайдера ключа подходящего нет.

G>При чем тут это?
AP>>Кстати, то, что СУБД не оптимизирует вот такое "... = @p1 OR @p1 IS NULL" связанно именно с кэшем планов. Либо надо бегать по дереву и тогда теряем в производительности кэша, либо отдать это на откуп пользователю, пусть он генерирует разные тексты для запросов, которые будут разными ключами в кэше.
G>Да, и linq тут спасает. Хоть и "ключа поодходящего нет" (с)
Это "спасение" за счет уменьшения производительности кэша. Разработчики СУБД давно бы сделали это, но не считаю, что это стоит потерь производительности кэша. А изготовители LINQ провайдеров вынуждены хотя бы таким кэшем прикрывать уж совсем неприличные тормоза (на неприлично простой задаче по генерации текста).

G>Именно, и проекции попапил в том числе в подзапросы. Как склейкой строк такое повторить?

Выше уже приводил код.

G>Ты чего курил? В этой теме уже раз 100 приводили декомпозицию IQueryable, хоть комбинаторами (в том числе обобщенными), хоть руками деревья выражений пиши, хоть dlinq (который используется в новых веб-формах для фильтров и сортировок).

100-ый раз повторяю, Хейлсберг не разрабатывал LINQ для построения запросов. А у вас доступа к компилятору нет, поэтому ваши решения либо сводят всю идею linq-а на нет, либо убогие частные случаи.
Re[30]: Entity Framework за! и против!
От: IT Россия linq2db.com
Дата: 10.07.14 18:51
Оценка: +1
Здравствуйте, Alexander Polyakov, Вы писали:

AP>Был такой old-school-ый подход выделять DAL и покрывать его тестами. Писать такие тесты довольно рутинное занятие. А рутинные, однообразные операции надо отделять и поручать машине. Вот я это и сделал.


Понятно. Т.е ты решил типичную задачу для типо-опасных инструментов — покрытие как можно большего количества кода юнит тестами, чтобы убедиться, что этот код не упадёт в рантайм. Т.е. ты решил проблему, которая для типо-безопасных инструментов просто не существует.

Что тут можно сказать. Во-первых, такие тесты будут работать либо бесконечно долго, либо не дадут 100% гарантии. Скорее всего поначалу они будут работать приемлемо долго, а с ростом кодовой базы приемлемо будет плавно переходить в неприемлемо. При этом 100%-го покрытия всё равно не будет. А вот компилятор даёт 100% гарантии типо-безопасности без дополнительных временных накладных расходов. Т.е. как я уже сказал, такой проблемы просто не существует и решать её не надо. Во-вторых, такой подход принуждает к использованию отдельного слоя, т.е. диктует разработчику архитектуру приложения, что всегда является несомненным минусом. В-третьих, сколько бы ни было тестов и каким бы не было покрытие, но нахождение ошибки всё равно откладывается на неопределённый срок, до тех пор пока программист не запустит тесты. При этом он может что-нибудь сломать и узнать об этом через пол часа, когда он занимается уже совсем другой задачей. А для типизированных решений ошибки видны уже в студии при наборе текста, ещё до копмиляции. При этом точность диагностики абсолютная, а тест выдаёт лишь примерную локализацию и как правило не очень внятную причину ошибки.

Что касается конкретного решения. Ковыряние в IL — это, конечно, прикольно, но ещё больше замедляет выполнение тестов, ещё больше накладывает ограничений на код и ещё больше зажимает приложение в тисках предлагаемой архитектуры. Решение, скажем, на атрибутах могло бы быть гораздо проще и более гибким. К тому же, насколько мне известно, подобные решения уже существуют в том числе и от MS.
Если нам не помогут, то мы тоже никого не пощадим.
Re[36]: Entity Framework за! и против!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.07.14 21:27
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

G>>Не понял, как проекция пропушится во все подзапросы?

AP>Чего? Нормально условие задачи сформулировать можешь?
Еще раз: сгенери сложный запрос с помощью linq, сделай .select с проекцией и увидишь, что проекции попали во все подзапросы.


G>>>>Даже если в подзапросе группировка, которую sql сам не соптимизирует.

AP>>>Proof link в студию или ты опять сочиняешь.
G>>Так попробуй сам сделать.
AP>Как же я сделаю то, чего нет? Короче, слив засчитан.
Да просто на SQL напиши запрос с подзапросом, в котором есть группировка и посмотри план.
Примерно так:

select field1 from (select field1, field2,... from table group by field1, field2,...)


SQL Server в этом случае сам не протакливает проекции в позапросы, а честно выполнит все вычисления с затягиванием данных с диска, даже если это совсем неоптимально.


AP>>>В СУБД движок, который перезаписывает запрос и генерирует план его выполнения, гораздо круче любого LINQ провайдера. И СУБД честно отводит на это ощутимое время, а потом использует кэш. Тут важно то, что ключом в кэше является сама строка запроса. А у LINQ провайдера ключа подходящего нет.

G>>При чем тут это?
AP>>>Кстати, то, что СУБД не оптимизирует вот такое "... = @p1 OR @p1 IS NULL" связанно именно с кэшем планов. Либо надо бегать по дереву и тогда теряем в производительности кэша, либо отдать это на откуп пользователю, пусть он генерирует разные тексты для запросов, которые будут разными ключами в кэше.
G>>Да, и linq тут спасает. Хоть и "ключа поодходящего нет" (с)
AP>Это "спасение" за счет уменьшения производительности кэша.
Это же лучше, чем уменьшение производительности запроса. Если запросов много, то планы из кеша не будут вытеснены, а если мало, то пофиг.

AP>Разработчики СУБД давно бы сделали это, но не считаю, что это стоит потерь производительности кэша.

Разработчики СУБД рассчитывают на то, что разработчики приложений будут писать запросы со стабильными планами. Дополнительный анализ стабильности плана может дорого стоить.
Но люди это люди, и они стремятся сократит затраты на разработку и поддержку, поэтому пишут запросы общего вида, что ведет к снижению эффективности.
Кстати Oracle умеет определять такие проблемы с планами и генерирует разные планы автоматом.

AP>А изготовители LINQ провайдеров вынуждены хотя бы таким кэшем прикрывать уж совсем неприличные тормоза (на неприлично простой задаче по генерации текста).

Какие неприличные тормоза? 0,4 мс на запрос, это меньше статистической погрешности от общего времени выполнения запроса.

Твое решение тратит гораздо больше времени в процессе написания, причем время программистов на 3 порядка дороже, чем время железки.

G>>Именно, и проекции попапил в том числе в подзапросы. Как склейкой строк такое повторить?

AP>Выше уже приводил код.
Ты не понял. Вот есть Linq запрос, который генерирует sql такого вида:

select field1, field2,... from (select field1, field2,... from t where...)


Потом выполняется .Select(e => e.field1) и результирующий SQL получается такой:

select field1 from (select field1 from t where...)


Рассчитывать что сам SQL Server такое соптимизирует нельзя.

Вот и как это сделать склейкой строк?


G>>Ты чего курил? В этой теме уже раз 100 приводили декомпозицию IQueryable, хоть комбинаторами (в том числе обобщенными), хоть руками деревья выражений пиши, хоть dlinq (который используется в новых веб-формах для фильтров и сортировок).

AP>100-ый раз повторяю, Хейлсберг не разрабатывал LINQ для построения запросов. А у вас доступа к компилятору нет, поэтому ваши решения либо сводят всю идею linq-а на нет, либо убогие частные случаи.
Если повторить чушь 100 раз она правдой не ставит.
Кстати Linq делал не Хейлсберг, а Мейер. Он подобное еще в 90-х делал на хаскеле, именно с прицелом на построение SQL запросов из кода (внезапно).
Доступ к компилятору для генерации деревьев выражений не нужен. Компилятор только преобразует лябмды в Expression Tree. Никто тебе не мешает любое дерево выражений собрать руками и обработать его как захочешь. Примеры кода тебе уже приводили раз десять, которые по объему и скорости работы сильно выигрывают у твоего решения.

Причем как бы ты не старался, все равно бегать по деревьям ET оказывается быстрее, чем ковырять IL, а потом выполнять реальные запросы к базе. Да и качество генерируемого SQL у Linq повыше, чем у самописных запросов (а учитывая время, затраченное на написание — гораздо выше). Linq может сгенерировать столько вариантов запроса, сколько руками замучаешься писать и поддерживать, даже имея удобный механизм для склейки строк.
Re[37]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 11.07.14 08:24
Оценка:
G>Да просто на SQL напиши запрос с подзапросом, в котором есть группировка и посмотри план.
G>Примерно так:
G>
G>select field1 from (select field1, field2,... from table group by field1, field2,...)
G>

G>SQL Server в этом случае сам не протакливает проекции в позапросы, а честно выполнит все вычисления с затягиванием данных с диска, даже если это совсем неоптимально.
Давай полный source code: DDL скрипт базы данных, SQL запрос, LINQ запрос и сгенерированный LINQ-ом SQL. Пока это выглядит как твои фантазии. Кстати, такое часто встречается, любители linq такое нафантазируют о СУБД, что уши вянут.
Re[31]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 11.07.14 12:23
Оценка: 1 (1)
Игорь, всё же будет лучше, если ты прочитаешь мою ссылку. Иначе мы будем тратить время на разбор твоих заблуждений, которые не имеют отношения к моему решению.

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

Да, верно. Но также верно и симметричное утверждение. У типо-безопасных инструментов есть проблемы, которые просто не существуют для другого класса инструментов.

IT>Что тут можно сказать. Во-первых, такие тесты будут работать либо бесконечно долго, либо не дадут 100% гарантии. Скорее всего поначалу они будут работать приемлемо долго, а с ростом кодовой базы приемлемо будет плавно переходить в неприемлемо. При этом 100%-го покрытия всё равно не будет. А вот компилятор даёт 100% гарантии типо-безопасности без дополнительных временных накладных расходов.

Компилятор C# тоже может работать бесконечно долго. Например, вот на этом коде компилятору не хватает памяти и он падает:
    class Program
    {

        private static void Main()
        {
            M(x1 =>
              M(x2 =>
              M(x3 =>
              M(x4 =>
              M(x5 =>
              M(x6 =>
              M(x7 =>
              M(x8 =>
              M(x9 =>
              M(x10 =>
              M(x11 =>
              M(x12 =>
              M(x13 =>
              M(x14 =>
                x1.ToLower() + x2.ToUpper() +
                x3.ToLower() + x4.ToUpper() +
                x5.ToLower() + x6.ToUpper() +
                x7.ToLower() + x8.ToUpper()
                  ))))))))))))));
        }

        private static int M(Func<int, int> f)
        {
            return f(2);
        }

        private static string M(Func<string, string> f)
        {
            return f(""); 
        }

        private static string M(Func<long, string> f)
        {
            return f(""); 
        }
    }

Описание этой проблемы можно почитать здесь.

IT>без дополнительных временных накладных расходов.

При росте кодовой базы временные расходы на компиляцию тоже растут.

IT>Во-вторых, такой подход принуждает к использованию отдельного слоя, т.е. диктует разработчику архитектуру приложения, что всегда является несомненным минусом.

Это не верно. Ни какого отдельного слоя не требуется. Запросы Query<My>.New можно писать где угодно. Они будут найдены и протестированы.

IT>В-третьих, сколько бы ни было тестов и каким бы не было покрытие, но нахождение ошибки всё равно откладывается на неопределённый срок, до тех пор пока программист не запустит тесты. При этом он может что-нибудь сломать и узнать об этом через пол часа, когда он занимается уже совсем другой задачей. А для типизированных решений ошибки видны уже в студии при наборе текста, ещё до копмиляции. При этом точность диагностики абсолютная, а тест выдаёт лишь примерную локализацию и как правило не очень внятную причину ошибки.

Какие полчаса, на реальных проектах мы укладываемся в полторы секунды на все запросы. А если надо быстрее, запускаем проверку той части запросов, с которой работаем в данный момент, это несколько сот миллисекунд. Всё как при обычном unit-тестировании. Или ты в принципе против unit-тестирования?

IT>При этом точность диагностики абсолютная, а тест выдаёт лишь примерную локализацию и как правило не очень внятную причину ошибки.

Точность диагностики примерно такая же как при компиляции. В сообщении указывается файл и строка, где начинается запрос, сам запрос и сообщение от СУБД.

Есть даже Find Usages для сущностей базы данных: таблиц, колонок и т.д.

IT>Что касается конкретного решения. Ковыряние в IL — это, конечно, прикольно, но ещё больше замедляет выполнение тестов, ещё больше накладывает ограничений на код и ещё больше зажимает приложение в тисках предлагаемой архитектуры. Решение, скажем, на атрибутах могло бы быть гораздо проще и более гибким. К тому же, насколько мне известно, подобные решения уже существуют в том числе и от MS.

Ни каких архитектурных тисков нет. Это ты придумал сам. По ссылке описано ровно обратное. Там последовательно описывается как мы наращиваем функционал и с чем мы оказываемся после каждого пункта. Такое последовательное описание дает четкое понимание для clear exit strategy. Можно выйти после любого из пунктов.

Отмечу, что класс Query всего лишь удобный способ заполнения SqlCommand. В остальном чистый ADO.NET.

IT>Решение, скажем, на атрибутах могло бы быть гораздо проще и более гибким.

На какие элементы кода ты предлагаешь навешивать атрибуты?

IT>К тому же, насколько мне известно, подобные решения уже существуют в том числе и от MS.

По правилам хорошего тона тут должны быть ссылки. Очень любопытно посмотреть.
Re[37]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 11.07.14 20:01
Оценка:
G>Кстати Oracle умеет определять такие проблемы с планами и генерирует разные планы автоматом.
Полного решения этой проблемы нет ни в одной СУБД, в которой есть кэш планов. Описано здесь.

Проблема не в реализации, проблема логическая. Полное решение проблемы не совместимо с быстрым кэшем планов. Еще раз повторю, то, что делает linq можно легко делать внутри СУБД, но этого не делают, поскольку СУБД не может себе позволить так транжирить производительность. А linq вынужден это делает. СУБД выставляет гибкий интерфейс текстовых запросов, и предлагает пользователям воспользоваться этой гибкостью и формулировать запрос точно без растранжиривания производительности.
Re[2]: Entity Framework за! и против!
От: Крякозавр  
Дата: 14.07.14 07:00
Оценка:
Здравствуйте, Dair, Вы писали:

D>Я как-то отстал от жизни, зачем пользоваться ORM вообще?


Почему начинаете издалека? Лучше сразу к делу — зачем нужно ООП.
Re[25]: Entity Framework за! и против!
От: Alexander Polyakov  
Дата: 16.07.14 20:36
Оценка:
IT>Может у тебя не самая свежая версия. Я довно nuget не обновлял. Может в этом проблема.
Только что обновил nuget пакеты. Ничего не поменялось. Здесь написано, что версия от July 11 2014, поэтому твое предположение о несвежей версии не прокатило. Разберись, плиз, в треде все данные есть.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.