it-swarm.com.de

Entspricht SQL ISNULL in LINQ?

In SQL können Sie ISNULL (null, '') ausführen. Wie würden Sie dies in einer Linq-Abfrage tun?

Ich habe eine Teilnahme an dieser Abfrage:

var hht = from x in db.HandheldAssets
        join a in db.HandheldDevInfos on x.AssetID equals a.DevName into DevInfo
        from aa in DevInfo.DefaultIfEmpty()
        select new
        {
        AssetID = x.AssetID,
        Status = xx.Online
        };

aber ich habe eine Spalte mit einem Bittyp, der nicht nullwertfähig ist (xx.online). Wie kann ich diesen auf false setzen, wenn er null ist?

49
MartGriff

Da aa die Menge/das Objekt ist, die/das null sein könnte, können Sie aa == null?

(aa/xx ist möglicherweise austauschbar (ein Tippfehler in der Frage); die ursprüngliche Frage handelt von xx, definiert jedoch nur aa)

d.h.

select new {
    AssetID = x.AssetID,
    Status = aa == null ? (bool?)null : aa.Online; // a Nullable<bool>
}

oder wenn Sie möchten, dass der Standardwert false ist (nicht null):

select new {
    AssetID = x.AssetID,
    Status = aa == null ? false : aa.Online;
}

Aktualisieren; Als Reaktion auf die Ablehnung habe ich mehr untersucht ... Tatsache ist, das ist der richtige Ansatz! Hier ist ein Beispiel für Northwind:

        using(var ctx = new DataClasses1DataContext())
        {
            ctx.Log = Console.Out;
            var qry = from boss in ctx.Employees
                      join grunt in ctx.Employees
                          on boss.EmployeeID equals grunt.ReportsTo into tree
                      from tmp in tree.DefaultIfEmpty()
                      select new
                             {
                                 ID = boss.EmployeeID,
                                 Name = tmp == null ? "" : tmp.FirstName
                        };
            foreach(var row in qry)
            {
                Console.WriteLine("{0}: {1}", row.ID, row.Name);
            }
        }

Und hier ist die TSQL - so ziemlich das, was wir wollen (es ist nicht ISNULL, aber es ist nah genug):

SELECT [t0].[EmployeeID] AS [ID],
    (CASE
        WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(10),@p0)
        ELSE [t2].[FirstName]
     END) AS [Name]
FROM [dbo].[Employees] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[FirstName], [t1].[ReportsTo]
    FROM [dbo].[Employees] AS [t1]
    ) AS [t2] ON ([t0].[EmployeeID]) = [t2].[ReportsTo]
-- @p0: Input NVarChar (Size = 0; Prec = 0; Scale = 0) []
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

QED?

58
Marc Gravell

Du kannst den ... benutzen ?? -Operator, um den Standardwert festzulegen, aber zuerst müssen Sie die Nullable -Eigenschaft in Ihrer dbml -Datei im erforderlichen Feld auf true setzen (xx.Online)

var hht = from x in db.HandheldAssets
        join a in db.HandheldDevInfos on x.AssetID equals a.DevName into DevInfo
        from aa in DevInfo.DefaultIfEmpty()
        select new
        {
        AssetID = x.AssetID,
        Status = xx.Online ?? false
        };
24
bruno conde

Ich habe oft dieses Problem mit Sequenzen (im Gegensatz zu diskreten Werten). Wenn ich eine Folge von Ints habe und diese summieren möchte, wird bei leerer Liste die Fehlermeldung "InvalidOperationException: Der Nullwert kann keinem Member mit dem Typ System.Int32 zugewiesen werden, der nicht nullwertfähig ist Art.".

Ich finde, ich kann das lösen, indem ich die Sequenz in einen nullbaren Typ umwandle. SUM und die anderen Aggregatoperatoren lösen diesen Fehler nicht aus, wenn eine Folge von nullfähigen Typen leer ist.

Also zum Beispiel so etwas

MySum = MyTable.Where(x => x.SomeCondtion).Sum(x => x.AnIntegerValue);

wird

MySum = MyTable.Where(x => x.SomeCondtion).Sum(x => (int?) x.AnIntegerValue);

Die zweite gibt 0 zurück, wenn keine Zeilen mit der where-Klausel übereinstimmen. (Der erste löst eine Ausnahme aus, wenn keine Zeilen übereinstimmen).

1
Slaggg

Der Typ ist anscheinend boolesch und kann daher niemals null sein und sollte standardmäßig false sein.

0
Ray Booysen