W mojej bazie danych w jednej z tabel mam kolumnę GUID z dopuszczalnymi wartościami null. Mam metodę z Guidem? parametr wstawiający nowy wiersz danych do tabeli. Jednak kiedy mówię myNewRow.myGuidColumn = myGuid pojawia się następujący błąd: "Nie można niejawnie przekonwertować typu" System.Guid? " do "System.Guid". "Nullable GUID
Odpowiedz
Interfejs API ADO.NET ma pewne problemy, jeśli chodzi o obsługę typów wartości zerowych (tzn. Po prostu nie działa poprawnie). Nie mieliśmy z tym problemów, więc doszliśmy do wniosku, że najlepiej jest ręcznie ustawić wartość na null, np.
myNewRow.myGuidColumn = myGuid == null ? (object)DBNull.Value : myGuid.Value
To bolesne, że dodatkowa praca ADO.NET powinny obsługiwać, ale nie wydaje się, aby to zrobić niezawodnie (nawet w 3.5 SP1). To przynajmniej działa poprawnie.
Widzieliśmy również problemy z przekazywaniem typów wartości zerowalnych do SqlParameters, w których wygenerowany SQL zawiera słowo kluczowe DEFAULT
zamiast NULL
dla wartości, dlatego zaleciłbym takie samo podejście podczas budowania parametrów.
OK; Jak zdefiniowano myGuidColumn i jak zdefiniowano myGuid?
Jeśli myGuid jest Guid?
i myGuidColumn jest Guid
, to błąd jest poprawne: trzeba będzie użyć myGuid.Value
lub (Guid)myGuid
uzyskać wartość (która rzuci jeśli jest null), czy może myGuid.GetValueOrDefault()
zwrócić GUID zerowy jeśli null.
Jeśli myGuid to Guid
, a myGuidColumn to Guid?
, to powinno działać.
Jeśli myGuidColumn to object
, prawdopodobnie potrzebujesz DBNull.Value
zamiast zwykłej wartości null.
Oczywiście, jeśli kolumna jest naprawdę pustych, to może po prostu chcesz mieć pewność, że jest Guid?
w folderze C# Kod ;-P
można użyć metody pomocnika:
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; }
}
}
lub :
internal static T CastTo<T>(object value)
{
return value != DBNull.Value ? (T)value : default(T);
}
Jeśli chcesz uniknąć pracy z pustych GUID w swojej kodu C# (osobiście, często znajduję to uciążliwe do pracy z pustych typów) można było gdzieś na początku ass ign Guid.Empty do danych .NET, które mają wartość null w db. W ten sposób nie musisz martwić się wszystkimi rzeczami .HasValue i po prostu sprawdź, czy zamiast tego jest myGuid != Guid.Empty
.
Używam już pustego identyfikatora GUID o innym "znaczeniu". – kjv
samo jak Greg Bukowej odpowiedź
myNewRow.myGuidColumn = (object)myGuid ?? DBNull.Value
Spróbuj System.Guid.Empty gdzie chcesz go mieć zerowy
Jeśli do metod rozszerzenie ...
/// <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);
}
Następnie możesz powiedzieć: myNewRow.myGuidColumn = myGuid.GetValueOrDBNull();
UWAGA: to wstaw wartość null, gdy myGuid == Guid.Empty
, możesz łatwo zmienić metodę, jeśli chcesz zezwolić na puste Guidy w kolumnie.
Trzeba rzucić null
do nullable Guid
, to jak to działa dla mnie:
myRecord.myGuidCol = (myGuid == null) ? (Guid?)null : myGuid.Value
Guid? _field = null;
if (myValue!="")//test if myValue has value
{
_field = Guid.Parse(myValue)
}
Rodzaj wyrażenia warunkowego nie może być ustalona, ponieważ nie istnieje niejawna konwersja między „” i 'System.DBNull System.Guid ' – kjv
Ah, przepraszam. Naprawiony. –
Możesz rozważyć użycie operatora koalescencji zerowej podczas pobierania wartości rezerwowej dla możliwego obiektu zerowego: "(object) myGuid ?? DBNull.Value" –