Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: Mike]
13.02.2012 15:34
|
|
|
Quote:
Опечатка вот здесь 'ModelPublication.ModelCode'? Тогда это не ловится, но оно также не ловится и в LINQ.
Да, это так.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Mike
|
Ызарг
|
|
|
|
Рег.: 02.11.2002
|
Сообщений: 8098
|
|
Рейтинг: 2147
|
|
|
Quote:
Да, это так.
То есть ты без данных проверишь эту опечатку в юнит тестах?
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: Mike]
13.02.2012 17:52
|
|
|
В теоретическом плане полагаю, что для задачи, которую ты сформулировал, решение существует. Если очень надо, то этим можно заняться. Однако, вернемся к вопросу, который обсуждаем здесь (это можно увидеть, если подняться на несколько уровней выше по треду, нажав 5 раз на линк 're::', начиная с твоего последнего сообщения): Quote:
При использовании Controllable Query для валидации запросов не требуются данные, сохраняемые в БД. Как с этим в твоих вручную написанных тестах?
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Mike
|
Ызарг
|
|
|
|
Рег.: 02.11.2002
|
Сообщений: 8098
|
|
Рейтинг: 2147
|
|
|
Quote:
В теоретическом плане полагаю, что для задачи, которую ты сформулировал, решение существует. Если очень надо, то этим можно заняться.
И так, для того, чтобы написать тесты под твоей библиотекой все равно нужны данные. И если покликать на "re:...", то можно прочитать:
Quote:
То есть при использовании твоей библиотеки все равно надо написать юнит тесты, которые одновременно покроют все, что делает твоя библиотека. А еще они будут кроссплатформенные, не будут накладывать кучу ограничений, и т.п.
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: Mike]
13.02.2012 18:38
|
|
|
Quote:
под твоей библиотекой
Controllable Query не требует наличие данных. Данные не нужны для работы Controllable Query.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Mike
|
Ызарг
|
|
|
|
Рег.: 02.11.2002
|
Сообщений: 8098
|
|
Рейтинг: 2147
|
|
|
Quote:
Controllable Query не требует наличие данных. Данные не нужны для работы Controllable Query.
При использовании Controllable Query все равно надо написать юнит тесты, которые одновременно покроют все, что делает Controllable Query. А еще они будут кроссплатформенные, не будут накладывать кучу ограничений, и т.п. При использовании Controllable Query нельзя написать юнит тесты без данных.
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: Mike]
13.02.2012 20:47
|
|
|
Quote:
При использовании Controllable Query все равно надо написать юнит тесты, которые одновременно покроют все, что делает Controllable Query.
Что значит надо? Есть разные мнения относительно объема unit-тестирования. Кто-то пишет много unit-тестов, кто-то меньше. Если вы оцениваете стоимость unit-тестов, то при этой оценке надо учитывать Controllable Query. Controllable Query может понизить ценность некоторых unit-тестов.
Еще Controllable Query найдет все запросы. При ручном unit-тестировании за покрытием тестами всех запросов следит человек. Людям свойственно ошибаться.
Вот тут ref1, ref2, ref3 сотрудники University of California занимаются 'Static Checking of Dynamically Generated Queries in Database Applications'. Controllable Query делает по сути такую же проверку.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Mike
|
Ызарг
|
|
|
|
Рег.: 02.11.2002
|
Сообщений: 8098
|
|
Рейтинг: 2147
|
|
|
Quote:
Кто-то пишет много unit-тестов, кто-то меньше.
Пока что мы выяснили, что в твоем случае либо тестов столько же; либо они по размеру меньше необходимой обвязки.
Quote:
Еще Controllable Query найдет все запросы.
Конечно же, не найдет. Потому что это поделие нельзя использовать для всех запросов. И даже когда оно будет готово хотя бы на 90%, а сейчас оно не готово и на 20%, ситуация не изменится.
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: Mike]
13.02.2012 23:07
|
|
|
в обоих пунктах ты ошибаешься
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
|
Quote:
здесь подставляется переменная или эскейптнутое значение?
Если смущает добавление параметра в коллекцию при вызове ToString, то вот прикрутил возможность добавлять параметры в стиле Dapper-а: code:
if (_.ModelCode.HasValue) builder.Append(@"
AND ModelPublication.ModelCode = @ModelCode", new { ModelCode = _.ModelCode.ValueOrEx });
Реализация заняла буквально три строчки: code:
public static StringBuilder Append<T>(this StringBuilder it, string value, T @params)
{
foreach (var propertyInfo in typeof (T).GetProperties())
((IParam) propertyInfo.GetValue(@params, null)).ToSql(propertyInfo.Name);
return it.Append(value);
}
В релизе рефлекшен заменю на emit.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
DDD2
|
sir
|
|
|
|
Рег.: 23.11.2007
|
Сообщений: 1103
|
|
Рейтинг: 246
|
|
|
Если так хочется статической типизации, то можно все запросы завернуть в хранимки или вьюхи. Тогда правильность хранимок и вьюх будет контролировать СУБД(в компайл-тайм). Единственным нетипизированным местом останется вызов хранимок из C# кода. Но тут все просто: если сигнатура процедуры поменялась, то надо искать все ее вызовы и исправлять. Это делается банальным грепом. Кстати, конкатенацию строк в таких простых случаях вообще можно убрать: code:
select * from foo where (:param1 is null or :param1 = foo.bar) and (:param2 is null or :param2 = foo.baz)
|
|
DDD2
|
sir
|
|
|
|
Рег.: 23.11.2007
|
Сообщений: 1103
|
|
Рейтинг: 246
|
|
Re: [C#] Querying
[re: DDD2]
16.02.2012 16:44
|
|
|
В ответ на:
Можно прикрутить Find Usages
В случае оракла зависимость хранимок от таблиц можно вытаскивать из базы простейшим sql запросом.
|
|
Mike
|
Ызарг
|
|
|
|
Рег.: 02.11.2002
|
Сообщений: 8098
|
|
Рейтинг: 2147
|
|
Re: [C#] Querying
[re: DDD2]
16.02.2012 16:54
|
|
|
Quote:
В случае оракла
Какого еще Оракла? Ты что, не знаешь, что не существует продуктов, выпущенных не Microsoft и не JetBrains?
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: DDD2]
16.02.2012 22:44
|
|
|
Quote:
Если так хочется статической типизации, то можно все запросы завернуть в хранимки или вьюхи. Тогда правильность хранимок и вьюх будет контролировать СУБД(в компайл-тайм). Единственным нетипизированным местом останется вызов хранимок из C# кода
для не динамического sql-я таких решений полным полно, в этом случае C#-методы могут просто генерироваться по хранимым процедурам. Но в реальности часто требуется динамических sql. Не городили бы тогда LINQ.
Quote:
select * from foo where (:param1 is null or aram1 = foo.bar) and (:param2 is null or aram2 = foo.baz)
это известный антипатерн, так делать не рекомендуется (не всегда подходит). По крайней мере, MS SQL Server генерирует не оптимальный план запроса. Как у других СУБД с этим, точно не скажу, но вроде это принципиальная трудность, связанная с кешированием планов запросов. Для того чтобы вырезать то или иное условие СУБД должна проанализировать запрос с учетом текущих параметров, а анализ запроса не делается, если план закеширован. Отказываться от кеширования планов запросов не всегда подходит.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
Re: [C#] Querying
[re: DDD2]
16.02.2012 22:47
|
|
|
Quote:
В случае оракла зависимость хранимок от таблиц можно вытаскивать из базы простейшим sql запросом.
в MS SQL Server тоже самое. Я об этом писал выше, когда рассказывал возможный алгоритм реализации Find Usages.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
|
Quote:
уже не совсем c#
Тут дело не в конкретном языке, а в статической типизации. Вот такой код должен компилироваться или нет?
Quote:
foreach (var record in db.ModelPublication .where ModelPublication.ModelCode == modelCode when not-null .where ModelPublication.ModelSequence == modelSequence when not-null .Select ModelPublication.PublicationId, ModelPublication.ModelCode when isYes, ModelPublication.ModelSequence) { Console.WriteLine(record.ModelCode); }
Естественно, интересует общий случай, когда на переменную 'isYes' не накладываются никакие ограничения, т.е. 'isYes' может быть параметром метода, результатом обращения к веб сервису и т.д.
Уникальность проекта Controllable Query как раз и состоит в том, что в нем удалось совместить динамические строки запросов и аналог статической типизации. Как отмечено в статье ref1
Quote:
Мы полагаем, что отсутствие поддержки динамических запросов является основной причиной отказа от большинства форм встраиваемого SQL [27].
Редактировал Shurik (18.02.2012 03:29)
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
DarkGray
|
Carpal Tunnel
|
|
|
|
Рег.: 30.09.2002
|
Сообщений: 31421
|
|
Рейтинг: 8956
|
|
|
Quote:
Тут дело не в C#-е, а в статической типизации.
есть два варианта раскрытия when внутри select-а.
в простом варианте, при наличии when тип поля заменяется (при необходимости) на Nullable. соответственно тип записи всегда один и тот же, и содержит поле ModelCode, и данный код скомпилится, но когда isYes - false, то ModelCode будет null
в более сложном варианте (но это мало применимо в .net-е, java-е, C++ и т.д. из-за отсутствия поддержки вариационных классов) создается два типа: один без поля ModelCode, второй с полем ModelCode. record при компиляции имеет первый тип, соответственно, чтобы получить доступ к ModelCode необходимо скастить ко второму типу.
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
|
Quote:
есть два варианта раскрытия when внутри select-а.
в простом варианте, при наличии when тип поля заменяется (при необходимости) на Nullable. соответственно тип записи всегда один и тот же, и содержит поле ModelCode, и данный код скомпилится, но когда isYes - false, то ModelCode будет null
в более сложном варианте (но это мало применимо в .net-е, java-е, C++ и т.д. из-за отсутствия поддержки вариационных классов) создается два типа: один без поля ModelCode, второй с полем ModelCode. record при компиляции имеет первый тип, соответственно, чтобы получить доступ к ModelCode необходимо скастить ко второму типу.
Оба варианта какое-то издевательство над статической типизацией.
|
not fluffing up the experience with features that will ultimately cause you a headache |
|
DarkGray
|
Carpal Tunnel
|
|
|
|
Рег.: 30.09.2002
|
Сообщений: 31421
|
|
Рейтинг: 8956
|
|
|
Quote:
Оба варианта какое-то издевательство над статической типизацией.
во втором варианте - все хорошо со статической типизацией, если ее правильно готовить.
|
|
Shurik
|
|
|
|
|
Рег.: 27.09.2003
|
Сообщений: 13646
|
|
Рейтинг: 787
|
|
|
плохо вот это: "скастить"
|
not fluffing up the experience with features that will ultimately cause you a headache |
|