Je ne recommanderais pas d'utiliser le DefaultIfEmpty
dans ce cas, puisqu'il produit un SQL assez grand par rapport aux autres alternatives.
Regardez cet exemple :
Nous avons une liste de modules pour une page et nous voulons obtenir la valeur maximale de la colonne "Sort". Si la liste n'a pas d'enregistrements, alors null est retourné. DefaultIfEmpty
vérifie la présence de null et renvoie la valeur par défaut du type de données de la colonne lorsque celle-ci est nulle.
var max = db.PageModules.Where(t => t.PageId == id).Select(t => t.Sort).DefaultIfEmpty().Max();
Cela produit le SQL suivant :
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MAX([Join1].[A1]) AS [A1]
FROM ( SELECT
CASE WHEN ([Project1].[C1] IS NULL) THEN 0 ELSE [Project1].[Sort] END AS [A1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent1].[Sort] AS [Sort],
cast(1 as tinyint) AS [C1]
FROM [dbo].[PageModules] AS [Extent1]
WHERE [Extent1].[PageId] = @p__linq__0 ) AS [Project1] ON 1 = 1
) AS [Join1]
) AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=11
go
Si, au lieu de cela, nous transformons la colonne en nullable et que nous laissons Convert.ToInt32()
traiter le null comme tel :
var max = Convert.ToInt32(db.PageModules.Where(t => t.PageId == id).Max(t => (int?)t.Sort));
Nous obtenons alors le SQL suivant :
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MAX([Extent1].[Sort]) AS [A1]
FROM [dbo].[PageModules] AS [Extent1]
WHERE [Extent1].[PageId] = @p__linq__0
) AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=11
go
Je peux vraiment recommander l'utilisation d'ExpressProfiler pour vérifier le SQL qui est exécuté : http://expressprofiler.codeplex.com/
La dernière expression Linq peut également être écrite comme suit :
var max = Convert.ToInt32(db.PageModules.Where(t => t.PageId == id).Select(t => (int?)t.Sort).Max());
et produiront le même SQL, mais j'aime bien la méthode plus concise .Max(t => (int?)t.Sort)
.