2011-01-12 14 views
6

Hay una colección de tipos de dispositivos, algunos de los cuales admiten configuración (es) de configuración. Estoy tratando de obtener una lista de todos los tipos de dispositivos y cualquier configuración aplicable.Linq Unión exterior izquierda - DefaultIfEmpty Error

Esta consulta no está recogiendo dispositivos que no tienen DeviceParameters. Si añado el .DefaultIfEmpty() como se muestra a continuación, me sale este error:

"El reparto de tipo de valor 'Int64' fracasaron porque el valor materializado es nulo cualquier parámetro genérico del tipo de resultado o la consulta deben utilizar. un tipo de nullable ".

¿Cuál es el synatx correcto para DefaultIfEmpty?

  var Devices = from d in dc.DeviceTypes 
         join p in dc.DeviceParameters on d.TypeID equals p.TypeID into tmpTable 
         from items in tmpTable.DefaultIfEmpty() 
         group items by d.DeviceName into g 
         select new 
         { 
          DeviceName = g.Key, 
          settings = from s in g 
            select new 
            { 
             ParamName = s.ParamName, 
             Param1 = s.Param1, 
             Param2 = s.Param2, 
             Param3 = s.Param3 
            } 
         }; 
+0

¿Ha intentado convertir ambos TypeIDs a nullable int? "on (int?) d.TypeID es igual a (int?) p.TypeID en" ... –

+0

Jacob: Gracias por la sugerencia, pero el mismo error ocurre incluso con el elenco. –

+0

:). Vale la pena intentarlo y gracias por la actualización. Me alegro de que hayas recibido una respuesta calificada. –

Respuesta

4

Si ha definido la relación de clave externa, creo que la solución es bastante sencilla, a menos que me falta algo:

var Devices = dc.DeviceTypes 
    .Select(p=>new 
     { 
      DeviceName = p.DeviceName , 
      settings = p.DeviceParameters 
       .Select(q=>new 
       { 
        ParamName = p.ParamName, 
        Param1 = q.Param1, 
        Param2 = q.Param2, 
        Param3 = q.Param3 
       }) 
     }); 

De todas formas, probablemente hacer la parte de configuración de la siguiente manera:

settings = p.DeviceParameters.ToList() 
+0

¡Gracias! Eso devuelve lo que necesito. –

+0

Fyi, p.DeviceParameters.ToList() dio este error: LINQ to Entities no reconoce el método 'System.Collections.Generic.List'1 [Instruments.DeviceParameters] ToList [DeviceParameters] (System.Collections.Generic.IEnumerable' 1 [Instruments.DeviceParameters]) 'método, y este método no se puede traducir a una expresión de tienda. –

+0

Ohhh ya veo. No sabía que no funciona de esa manera, soy nuevo en LINQ para las entidades. Thx para compartir =) – Francisco

1

creo que el problema que está viendo con su consulta es que al utilizar el DefaultIfEmpty() llamada que está a continuación, tratando de tirar de los valores de una o nula bject. Si usted tiene un DeviceType válida, pero no tienen ningún DeviceParameters asignan a continuación, cuando se está tratando de materializar la propiedad configuración con esta declaración:

settings = from s in g 
select new 
{ 
    ParamName = s.ParamName, 
    Param1 = s.Param1, 
    Param2 = s.Param2, 
    Param3 = s.Param3 
} 

Se trata de crear un nuevo objeto y el objeto de "s" es nulo, por lo que intentar acceder a la propiedad ParamName o Param1, etc. no funcionará. Probé el mismo código dentro de LINQPad y cuando eliminé la llamada DefaultIfEmpty() todo funcionó.

Sin conocer las propiedades y sus tipos, no puedo estar seguro, pero como dije, basándome en la implementación de código similar en LINQPad obtuve resultados similares.

Cuestiones relacionadas