3 Stimmen

Nullable Guid in Linq to Sql ergibt unerwartetes Ergebnis

Ich habe eine einfache SQL-Tabelle, die eine Reihe hierarchischer Kategorien und Unterkategorien definiert - beachten Sie, dass die ParentCategoryId für 'Top-Level'-Kategorien null sein kann...

CREATE TABLE [dbo].[Kategorie](
    [KategorieId] [uniqueidentifier] NOT NULL,
    [ElternKategorieId] [uniqueidentifier] NULL,
    [Name] [nvarchar](50) NOT NULL
)

Wenn ich dann einen Linq-Ausdruck erstelle, um eine bestimmte Kategorie nach Name und ParentCategoryId zu finden, finde ich, dass ich kein korrektes Ergebnis erhalte, wenn ich einer Guid?-Variable den Wert null zuweise:

Guid? parentCategoryId = null;

var kategorie = dc.Kategorien
    .Where(k => (
        (k.Name == "Fred") &&
        (k.ElternKategorieId == parentCategoryId)
));

Dies liefert nicht das gleiche Ergebnis wie:

var kategorie = dc.Kategorien
    .Where(k => (
        (k.Name == "Fred") &&
        (k.ElternKategorieId == null)
));

Nach meinen Recherchen im Web haben auch andere dieses Problem gehabt, aber ich konnte keine saubere Lösung finden, um das Problem zu beheben.

Über Ideen würde ich mich sehr freuen. Danke.

Zusätzliche Informationen Hier sind die durch LINQ generierten SQL-Anweisungen für einen ersten Guid? null-Parameter und dann für einen einfachen null-Parameter:

-- Mit Guid? null-Parameter: gibt einen leeren Datensatz zurück
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred'
DECLARE @p1 UniqueIdentifier SET @p1 = null
SELECT [t0].[KategorieId], [t0].[ElternKategorieId], [t0].[Name], [t0].[Zeitstempel]
FROM [dbo].[cad_ScoKategorie] AS [t0]
WHERE ([t0].[Name] = @p0) AND ([t0].[ElternKategorieId] = @p1)

-- Mit null-Parameter - gibt einen einzelnen (korrekten) Datensatz zurück
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred'
SELECT [t0].[KategorieId], [t0].[ElternKategorieId], [t0].[Name], [t0].[Zeitstempel]
FROM [dbo].[cad_ScoKategorie] AS [t0]
WHERE ([t0].[Name] = @p0) AND ([t0].[ElternKategorieId] IS NULL)

Wie Sie sehen können, vergleicht die erste Option die ElternKategorieId mit einem null-Wert, während die zweite Methode prüft, ob ElternKategorieId IS NULL ist - was korrekt ist

0 Stimmen

Warum setzen Sie nicht parentid für den ersten auf Null, wenn der Rest ab 1 beginnt.

1 Stimmen

Können Sie die generierte SQL-SELECT-Anweisung anzeigen?

0 Stimmen

Was sind die unterschiedlichen Ergebnisse.

8voto

Jon Skeet Punkte 1325502

Nein, das ist leider ein ziemlich häufiges Problem. Der Workaround besteht darin, explizit mit null zu vergleichen:

.Where(c => c.Name == Fred &&
           ((c.ParentCategoryId == parentCategoryId) ||
            (c.ParentCategoryId == null && parentCategoryId == null)))

Alternativ können Sie die Überprüfung außerhalb der Abfrage durchführen (um zu ändern, welcher Filter verwendet wird):

var category = dc.Categories.Where(c => c.Name == "Fred");
category = parentCategoryId == null 
    ? category.Where(c => c.ParentCategoryId == null)
    : category.Where(c => c.ParentCategoryId == categoryId);

0 Stimmen

Vielen Dank Jon, Ihr Workaround funktioniert gut und überwindet das Problem. Es ist sehr einfach, dieses Problem auf Code-Ebene zu übersehen, daher sei sehr vorsichtig, wenn Sie nullable Typen vergleichen. Vielen Dank für Ihre Hilfe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X