#c# #sql-server #orm #dapper
#c# #sql-сервер #orm #dapper
Вопрос:
Я пытаюсь использовать Dapper в первый раз, но сразу столкнулся с проблемой, заключающейся в том, что, похоже, Dapper не может обрабатывать обнуляемые поля. Это меня сильно удивляет, поскольку они чрезвычайно распространены.
Если у меня есть обнуляемое логическое поле в моей базе данных SQL Server и я пытаюсь использовать Dapper для заполнения обнуляемого логического свойства в моем классе C #, выдается исключение, если логическое поле содержит нулевое значение:
System.FormatException: String was not recognized as a valid Boolean.
Есть ли какое-либо исправление или обходной путь для этого? Мне трудно поверить, что Dapper не может справиться с этим, поскольку похоже, что это существует уже некоторое время, и это чрезвычайно простая функция.
РЕДАКТИРОВАТЬ: это была моя ошибка! Мой столбец на самом деле был nvarchar, который случайно содержал 0 или 1, и как таковой, я не заметил. Изменение его на BIT (или свойства C # на «string?») устраняет проблему.
Комментарии:
1. Можете ли вы опубликовать свое определение таблицы и свой код Dapper, который выдает исключение?
2. Тот факт, что он упоминает
string
, говорит мне, что проблема может заключаться в ваших данных / запросе… какой здесь столбец?3. На самом деле столбец является результатом объединения по ЛЕВОМУ краю и отображается в SSIS как DB null. Возможно, Dapper не распознает это как bool?
4. @NickG ну, возможно, на самом деле это вообще не bool; каковы здесь фактические данные?
5. Исходный столбец определенно является обнуляемым битовым (логическим) полем. Однако при выполнении LEFT JOIN, возможно, SQL Server преобразует его во что-то другое?
Ответ №1:
Да, работает просто отлично:
public void SO24607639_NullableBools()
{
var obj = connection.Query<HazBools>(
@"declare @vals table (A bit null, B bit null, C bit null);
insert @vals (A,B,C) values (1,0,null);
select * from @vals").Single();
obj.IsNotNull();
obj.A.Value.IsEqualTo(true);
obj.B.Value.IsEqualTo(false);
obj.C.IsNull();
}
class HazBools
{
public bool? A { get; set; }
public bool? B { get; set; }
public bool? C { get; set; }
}
Комментарии:
1. Вы правы. Я идиот. Мой столбец был сопоставлен с NVARCHAR, и я почему-то не заметил, поскольку мой предыдущий (не-dapper) код каким-то образом справился с этим нормально… Возможно, мне следует удалить этот вопрос?
2. @NickG полностью зависит от вас
3. Я оставлю это здесь на случай, если кто-нибудь еще допустит ту же глупую ошибку 🙂
Ответ №2:
Поскольку Dapper не выполняет слишком много операций, набор записей, поступающий из базы данных, содержит строку, указанную в ошибке. Попробуйте проверить тип столбца, и когда это станет ясно, вы сможете соответствующим образом изменить класс DTO или каким-либо образом преобразовать его в запросе.