50 votes

Équivalent de SQL ISNULL dans LINQ?

En SQL, vous pouvez exécuter un ISNULL (null, '') comment procéder dans une requête linq?

J'ai une jointure dans cette requête:

 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
        };
 

mais j'ai une colonne qui a un type de bit non nullable (xx.online), comment puis-je définir cette valeur sur false si elle est nulle?

59voto

Marc Gravell Points 482669

Depuis aa est l'objet qui peut être null, pouvez-vous vérifier aa == null ?

(aa / xx pourraient être interchangeables (une faute de frappe dans la question); la question d'origine parle de xx mais seulement définit aa)

c'est à dire

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

ou si vous voulez la valeur par défaut est false (pas null):

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


Mise à jour; en réponse à la downvote, je l'ai étudié plus... le fait est que c'est la bonne approche! Voici un exemple sur les Comptoirs:

        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);
            }
        }

Et voici le TSQL - à peu près ce que nous voulons (il n'est pas ISNULL, mais il est assez proche):

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

CQFD?

24voto

bruno conde Points 28120

Vous pouvez utiliser le ?? opérateur pour définir la valeur par défaut , mais vous devez d' abord définir le Nullable bien à true dans votre fichier dbml dans le champ obligatoire ( 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
        };
 

1voto

Slaggg Points 2399

J'ai souvent ce problème avec des séquences (par opposition à des valeurs discrètes). Si j'ai une séquence d'entiers, et je veux SOMME, quand la liste est vide, je vais recevoir le message d'erreur "exception InvalidOperationException: La valeur null ne peut pas être attribué à un membre avec Système de type.Int32 qui est un non nullable type de la valeur.".

Je trouve que je peux résoudre ce par la coulée de la séquence de type nullable. SOMME et les autres opérateurs d'agrégation ne jetez pas cette erreur si une séquence de types nullables est vide.

Ainsi, par exemple, quelque chose comme ça

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

devient

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

Le second renvoie 0 quand n lignes correspondent à la clause where. (le premier déclenche une exception lorsqu'aucune correspondance de lignes).

0voto

Ray Booysen Points 10606

On dirait que le type est booléen et ne peut donc jamais être null et devrait être false par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X