Équivalent de SQL ISNULL dans LINQ?
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?
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.