Невозможно преобразовать значения varchar в тип данных int

Я пошел по многим путям и создал множество реализаций репозиториев в разных проектах и ​​... Я бросил полотенце и отказался от него, вот почему.

Кодирование исключения

Вы кодируете для 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, поэтому у нас есть возможность использовать разные провайдеры и работать с объектными графами в хорошо связанном ключе среди многих вещей. Некоторые абстракции полезны, а некоторые нет.

Надеюсь, это поможет кому-то в интернетах где-то ...

0
задан SphunaR 17 January 2019 в 12:41
поделиться

2 ответа

Вы не можете преобразовать десятичное представление 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?

0
ответ дан Larnu 17 January 2019 в 12:41
поделиться

Не понимаю, почему вы хотите заменить, чтобы. и затем все равно разыгрывается как 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
0
ответ дан Pawel Czapski 17 January 2019 в 12:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: