2009-01-05 28 views
48

En SQL puede ejecutar un ISNULL (nulo, '') ¿cómo haría esto en una consulta de linq?¿Equivalente a SQL ISNULL en LINQ?

He en una combinación en esta consulta:

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

pero tengo una columna que tiene un tipo de bits que no es anulable (xx.online) ¿Cómo puedo poner esto a falso si es nulo?

+3

¿Quiere decir "aa.Online"? "xx" no está definido en ningún lado ... –

Respuesta

55

Desde aa es el conjunto/objeto que podría ser nulo, ¿puedes verificar aa == null?

(aa/xx podrían ser intercambiables (un error tipográfico en la cuestión); la pregunta original habla de xx pero sólo define aa)

es decir

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

o si desea que el defecto sea false (no null):

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

Actualización; en respuesta al voto a favor, he investigado más ... ¡el hecho es que este es el enfoque correcto! He aquí un ejemplo de Neptuno:

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

Y aquí está la TSQL - más o menos lo que queremos (no es ISNULL, pero es lo suficientemente cerca):

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?

+0

¡Es difícil mantener el representante por encima de 200 por día!?!?! Sí claro. Comprobé [System.Data.Linq.SqlClient.SqlMethods] (http://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.aspx) y no hay ningún método para garantizar Se produce el 'ISNULL' de SQL así que usaré tu código :-) – dumbledad

+0

¿Qué tal hacer un JOIN con ISNULL? ¿Funcionará lo mismo? ¿es necesario? – Matt

+0

Sí y lo probé y lo suficientemente cerca no lo cortó. creó una declaración de caso así que cuando la ejecuté, devolvió demasiados datos. Después de eliminar la declaración de caso, el sql volvió bien ... lo siento por degradar esto – Clarence

0

Parece que el tipo es booleano y, por lo tanto, nunca puede ser nulo y debe ser falso de manera predeterminada.

+1

¿Cómo puedes hacer que sea falso por defecto si es de una unión? – MartGriff

+0

¿Será falso por defecto seguramente? Es un booleano y no se ha establecido, por lo que debería ser falso. ¿Qué estas viendo? –

23

Usted puede utilizar el operador ?? para establecer el valor por defecto pero primero hay que establecer la propiedad Nullable a true en su dbml archivo en el campo requerido (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 
     }; 
1

A menudo tengo este problema con las secuencias (a diferencia de los valores discretos). Si tengo una secuencia de entradas, y quiero SUMARlas, cuando la lista esté vacía, recibiré el error "InvalidOperationException: El valor nulo no se puede asignar a un miembro con el tipo System.Int32, que es un valor que no admite nulos. tipo.".

Me parece que puedo resolver esto al convertir la secuencia a un tipo que admite nulo. SUM y los otros operadores agregados no arrojan este error si una secuencia de tipos anulables está vacía.

Así, por ejemplo, algo como esto

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

convierte

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

El segundo devolverá 0 cuando no hay filas coincide con la cláusula where. (el primero arroja una excepción cuando no coinciden las filas).