Question

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 dont le type de bit est non nullable (xx.online). Comment puis-je définir cette valeur sur false si elle est nulle?

Était-ce utile?

La solution

Puisque aa est l'ensemble / l'objet pouvant être null, pouvez-vous vérifier aa == null ?

( aa / xx peut être interchangeable (une faute de frappe dans la question); la question d'origine parle de xx mais ne définit que aa )

c'est-à-dire

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

ou si vous souhaitez que la valeur par défaut soit false (et non null ):

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

Mettre à jour; En réponse à la baisse de voix, j'ai enquêté davantage ... le fait est que c'est la bonne approche! Voici un exemple sur 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);
            }
        }

Et voici la TSQL - à peu près ce que nous voulons (ce n'est pas ISNULL , mais c'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

QED?

Autres conseils

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

J'ai souvent ce problème avec les séquences (par opposition aux valeurs discrètes). Si j'ai une séquence d'ints et que je souhaite les cumuler, lorsque la liste est vide, je reçois le message d'erreur "InvalidOperationException: la valeur null ne peut pas être affectée à un membre de type System.Int32 qui est non nullable. type de valeur. ".

Je trouve que je peux résoudre ce problème en convertissant la séquence en un type nullable. SUM et les autres opérateurs d'agrégat ne génèrent pas cette erreur si une séquence de types nullable est vide.

Ainsi, par exemple, quelque chose comme ceci

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

devient

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

Le second renverra 0 si aucune ligne ne correspond à la clause where. (le premier lève une exception quand aucune ligne ne correspond).

On dirait que le type est booléen et ne peut donc jamais être nul. Par défaut, il devrait être faux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top