Обнуляемый GUID
-
03-07-2019 - |
Вопрос
В моей базе данных, в одной из таблиц, у меня есть столбец GUID с разрешенными нулевыми значениями.У меня есть метод с Guid?параметр, который вставляет новую строку данных в таблицу.Однако, когда я говорю myNewRow.myGuidColumn = myGuid, я получаю следующую ошибку:"Не удается неявно преобразовать тип 'System.Guid?' в 'System.Guid'".
Решение
ADO.NET API имеет некоторые проблемы, когда дело доходит до обработки типов значений с нулевым значением (т. е.это просто работает некорректно).У нас не было конца проблемам с этим, и поэтому мы пришли к выводу, что лучше всего вручную установить значение null, например
myNewRow.myGuidColumn = myGuid == null ? (object)DBNull.Value : myGuid.Value
Это болезненная дополнительная работа, с которой ADO.NET следует справиться, но, похоже, она не выполняется так надежно (даже в версии 3.5 SP1).Это, по крайней мере, работает корректно.
Мы также видели проблемы с передачей типов значений с нулевым значением в SqlParameters, где сгенерированный SQL включает ключевое слово DEFAULT
вместо того, чтобы NULL
для значения so я бы рекомендовал такой же подход при построении параметров.
Другие советы
ОК;как определяется myGuidColumn и как определяется myGuid?
Если myGuid является Guid?
и myGuidColumn - это Guid
, тогда ошибка верна:вам нужно будет использовать myGuid.Value
, или (Guid)myGuid
чтобы получить значение (которое будет выдано, если оно равно нулю), или, возможно myGuid.GetValueOrDefault()
чтобы вернуть нулевой guid, если null.
Если myGuid является Guid
и myGuidColumn - это Guid?
, тогда это должно сработать.
Если myGuidColumn равен object
, вам , вероятно , понадобится DBNull.Value
вместо обычного null.
Конечно, если столбец действительно имеет значение null, вы можете просто захотеть убедиться, что это так Guid?
в коде C# ;-p
то же, что и ответ Грега Бича
myNewRow.myGuidColumn = (object)myGuid ?? DBNull.Value
Вы должны разыграть null
к a nullable Guid
, вот как это сработало у меня :
myRecord.myGuidCol = (myGuid == null) ? (Guid?)null : myGuid.Value
Попробуйте System.Guid.Empty, где вы хотите, чтобы оно было нулевым
Если вы хотите избежать работы с обнуляемыми идентификаторами GUID в вашем коде c # (лично я часто нахожу громоздкой работу с обнуляемыми типами), вы могли бы где-нибудь пораньше назначить Guid.Пустой к .ЧИСТЫЕ данные, которые являются нулевыми в базе данных.Таким образом, вам не нужно беспокоиться обо всех .HasValue и просто проверьте, есть ли myGuid != Guid.Empty
вместо этого.
или:
internal static T CastTo<T>(object value)
{
return value != DBNull.Value ? (T)value : default(T);
}
Вы можете использовать вспомогательный метод:
public static class Ado {
public static void SetParameterValue<T>( IDataParameter parameter, T? value ) where T : struct {
if ( null == value ) { parameter.Value = DBNull.Value; }
else { parameter.Value = value.Value; }
}
public static void SetParameterValue( IDataParameter parameter, string value ) {
if ( null == value ) { parameter.Value = DBNull.Value; }
else { parameter.Value = value; }
}
}
Если вы интересуетесь методами расширения...
/// <summary>
/// Returns nullable Guid (Guid?) value if not null or Guid.Empty, otherwise returns DBNull.Value
/// </summary>
public static object GetValueOrDBNull(this Guid? aGuid)
{
return (!aGuid.IsNullOrEmpty()) ? (object)aGuid : DBNull.Value;
}
/// <summary>
/// Determines if a nullable Guid (Guid?) is null or Guid.Empty
/// </summary>
public static bool IsNullOrEmpty(this Guid? aGuid)
{
return (!aGuid.HasValue || aGuid.Value == Guid.Empty);
}
Тогда вы могли бы сказать:myNewRow.myGuidColumn = myGuid.GetValueOrDBNull();
ПРИМЕЧАНИЕ:Это приведет к вставке null, когда myGuid == Guid.Empty
, вы могли бы легко настроить этот метод, если хотите разрешить использование пустых идентификаторов Guid в вашем столбце.
Guid? _field = null;
if (myValue!="")//test if myValue has value
{
_field = Guid.Parse(myValue)
}