Я пошел по многим путям и создал множество реализаций репозиториев в разных проектах и ... Я бросил полотенце и отказался от него, вот почему.
Кодирование исключения
Вы кодируете для 1% вероятность того, что ваша база данных изменится с одной технологии на другую? Если вы думаете о будущем состоянии своего бизнеса и говорите «да», то это возможность: а) у них должно быть много денег, чтобы позволить себе переход на другую технологию БД или б) вы выбираете технологию БД для развлечения или с ) что-то ушло ужасно неправильно с первой технологией, которую вы решили использовать.
Зачем выбрасывать богатый синтаксис LINQ?
LINQ и EF были разработаны так, чтобы вы могли делать с ним аккуратные вещи читать и пересекать графы объектов. Создание и поддержка репозитория, который может дать вам такую же гибкость, чтобы сделать это, является чудовищной задачей. По моему опыту в любое время, когда я создал репозиторий, я ВСЕГДА имел деловую логику, протекающую в слое репозитория, чтобы сделать запросы более эффективными и / или уменьшить количество обращений к базе данных.
Я не хочу создавать метод для каждой перестановки запроса, который я должен написать. Я мог бы также написать хранимые процедуры. Я не хочу GetOrder, GetOrderWithOrderItem, GetOrderWithOrderItemWithOrderActivity, GetOrderByUserId и т. Д. Я просто хочу получить основную сущность и пройти и включить граф объектов так, как вам нравится.
Большинство примеров репозиториев это фигня
Если вы не разрабатываете что-то ДЕЙСТВИТЕЛЬНО голые кости, как блог или что-то, что ваши запросы никогда не будут такими же простыми, как 90% примеров, которые вы найдете в Интернете, окружающих шаблон репозитория. Я не могу подчеркнуть это достаточно! Это то, что нужно проползать через грязь, чтобы понять. Всегда будет один запрос, который сломает ваш прекрасно продуманный репозиторий / решение, которое вы создали, и его не до тех пор, пока не начнется то, на что вы догадаетесь, и технический долг / эрозия.
t unit test me bro
Но как насчет модульного тестирования, если у меня нет репозитория? Как я буду издеваться? Просто вы этого не делаете. Давайте посмотрим на это с обоих углов:
Нет репозитория - вы можете издеваться над DbContext с помощью IDbContext или некоторых других трюков, но тогда вы действительно тестируете LINQ для объектов, а не LINQ to Entities, потому что запрос определяется во время выполнения ... ОК, так что это не хорошо! Итак, теперь это до теста интеграции, чтобы покрыть это.
С репозиторием - теперь вы можете издеваться над своими репозиториями и модулями тестировать слой (ы) между ними. Отлично? Ну, не так ... В вышеприведенных случаях, когда вам нужно протекать логику в уровень репозитория, чтобы сделать запросы более эффективными и / или менее попадающими в базу данных, как ваши обходные тесты могут покрыть это? Теперь он находится на уровне репо, и вы не хотите правильно тестировать IQueryable? Также давайте честно сказать, что ваши юнит-тесты не будут охватывать запросы, у которых есть 20 строк .Where()
, а .Include()
- связка связей и снова попадает в базу данных, чтобы делать все это другое: blah, blah, blah в любом случае, потому что запрос создается во время выполнения. Кроме того, поскольку вы создали хранилище, чтобы сохранить приоритет на верхних уровнях невежественным, если теперь вы хотите изменить технологию баз данных, извините, что ваши юнит-тесты вызывающе не гарантируют одинаковые результаты во время выполнения, вернутся к интеграционным тестам. Таким образом, вся точка репозитория кажется странной ..
2 цента
Мы уже теряем много функциональности и синтаксиса при использовании EF поверх простых хранимых процедур (объемные вставки, массовые удаления, CTE и т. Д.), Но я также код на C #, поэтому мне не нужно вводить двоичный код. Мы используем EF, поэтому у нас есть возможность использовать разные провайдеры и работать с объектными графами в хорошо связанном ключе среди многих вещей. Некоторые абстракции полезны, а некоторые нет.
Надеюсь, это поможет кому-то в интернетах где-то ...
Вы не можете преобразовать десятичное представление varchar
непосредственно в int
(SELECT CONVERT(int, '0.27');
потерпит неудачу с той же ошибкой). Вам нужно CONVERT
сначала значение decimal
, а затем int
. Итак, для вашего запроса:
SELECT POWIERZCHNIA,
CONVERT(int,CONVERT(decimal(3,2),REPLACE(POWIERZCHNIA, ',', '.')))
FROM v_analiza_cechy_produktow;
Обратите внимание, что я использовал decimal(3,2)
, поскольку у нас есть только одно значение выборки '0.27'
. вам скорее всего нужно будет выбрать другой масштаб и точность.
Это, однако, задает вопрос; почему вы храните десятичные значения как varchar
?
Не понимаю, почему вы хотите заменить, чтобы. и затем все равно разыгрывается как INT ..., нет никакого смысла делать это. Ниже должно работать нормально, пожалуйста, проверьте его.
SELECT CAST(CAST('0.27' AS DECIMAL(5,2)) * 100 as int)
SELECT
POWIERZCHNIA,
CAST((CAST(POWIERZCHNIA AS DECIMAL(5,2)) * 100) as INT)
FROM v_analiza_cechy_produktow
WHERE POWIERZCHNIA IS NOT NULL
РЕДАКТИРОВАТЬ
Это в основном тот же ответ, что и @Larnu, только что использовали CAST вместо CONVERT ...
РЕДАКТИРОВАТЬ
Вы можете использовать функцию ISNUMERIC для проверки POWIERZCHNIA
SELECT
POWIERZCHNIA,
CAST((CAST(POWIERZCHNIA AS DECIMAL(5,2)) * 100) as INT)
FROM v_analiza_cechy_produktow
WHERE IsNumeric(POWIERZCHNIA) = 1