2012-04-18 9 views
6

Veo un comportamiento extraño en mi modelo de Entity Framework. Tengo una consulta que tiene el siguiente aspecto:Marco de entidad devuelve nulo para una fila si la primera columna en esa fila es nula

var rows = (from alarm in context.Alarms 
      join temp in context.ListDetails on alarm.ListDetailId equals temp.ListDetailId into entries from entry in entries.DefaultIfEmpty() 
      join read in context.Reads  on alarm.ReadId  equals read.ReadId 
      join plate in context.Images  on alarm.ReadId  equals plate.ReadId 
      where alarm.IActive == 1 && ! alarm.TransmittedAlarm 
      where read.IActive == 1 
      where plate.IActive == 1 && plate.ImageTypeId == 2 
      select new { alarm, entry, read, plate }).ToArray(); 

La consulta devuelve todas las columnas en orden alfabético por el nombre de la columna. Resulta que esta columna es NULL para algunas filas en el conjunto de resultados. Cuando amplío la variable de filas en el depurador, veo que toda la fila es nula.

EDIT: Alguna aclaración.

Por "primera columna", me refiero a la primera columna de la primera fila, es decir, en "SELECCIONE A, B, C DE ...", quiero decir A. Simplemente sucede que la consulta que Entity Framework construye devuelve todas las columnas en el conjunto de resultados unidos en orden alfabético, y el primero alfabéticamente es anulable y es nulo para algunas filas.

La columna en cuestión no es una clave principal; si fuera una clave principal, no podría ser nula.

Cuando Entity Framework procesa las filas de los datos devueltos en objetos, busca el valor de la primera columna en cada fila. Si esa columna es nula, devuelve nulo para la fila, en lugar de un objeto con la propiedad correspondiente a esa columna establecida en nulo.

No creo que esto tenga nada que ver específicamente con una unión externa izquierda; simplemente sucede que mi consulta usa uno. No he hecho ninguna prueba para verificar esto, sin embargo, así que es solo una suposición.

¿Alguien ha visto esto antes? ¿Alguien tiene una solución para esto?

, Tony

+0

¿Necesitas una combinación izquierda? –

+0

¿En qué lugar se obtiene el error? –

+0

¿Podría publicar la consulta SQL que el EF envía al DB? –

Respuesta

1

Se utiliza en su DefaultIfEmpty unirse. Significa

Si hay artículos en entries que coinciden con el criterio de unirse a (alarm.ListDetailId equals temp.ListDetailId), quiero que usted ponga un solo valor por defecto de tipo ListDetail (que es null) en entries.

En este caso, EF genera un LEFT JOIN. De hecho, este código es la forma conocida de generar un LEFT JOIN con Linq2Sql o EF.

La declaración LEFT JOIN selecciona NULL valores para todas las columnas de la tabla si ninguna fila en la tabla coincide con el criterio JOIN. De hecho, la única columna que importa es la columna PK de la entidad. EF comprueba si el valor PK es NULL, decide que no existe entidad y pone null en entries. A continuación, obtiene null como el valor de propiedad entry de los resultados.

+0

Necesito la unión externa izquierda. El problema no es que la 'entrada' sea' NULL'; el problema es que la primera columna en la 'alarma' es' NULL' y toda la selección 'nueva {alarma, entrada, lectura, placa}' se devuelve como 'NULL', no solo' entrada'. –

6

Puedo confirmar que tengo exactamente el mismo problema: cuando la consulta SQL formada por EF tiene null en la primera columna del resultado, devuelve nulo en lugar de entidad. Significa exactamente siguientes:

using (var dc = new MyDbContext()) 
{ 
    var q = dc.Lands; //Lands is DbSet<Land> 
    q = q.Where(criteria); //this leads to SQL query returning null in first column, confirmed by profiler 
    var t = q.Single(); //t is now null 
} 

Si tomamos otro criterio, que no dan lugar a null en la primera columna, t es normal null entidad no.

Me parece que es un tipo de comportamiento/error oscuro en EF.

actualización

Después de varias horas de sondeo que he encontrado siguiente comportamiento. EF devuelve null para las entidades que tienen NULL en la primera columna de resultados (que rompe el comportamiento esperado), pero tiene varias nociones sobre qué columna poner primero en la lista de selección. Entonces, después de hacer que mi modelo sea consistente con mi estado de base de datos (lo que significa denotar todas las columnas de la base de datos NULLABLE y reemplazar las propiedades de navegación required con optional) - Estoy usando Code First, por lo que hay muchos lugares para ser explícitos sobre base de datos - Me las he arreglado para hacer que funcione.

Significa que debe verificar la definición de nivel de tienda de su modelo (según el paradigma que utilice, basado en el diseñador o basado en código, sería diferentes lugares) en su base de datos.

Cuestiones relacionadas