¿Por qué la instancia de tipo anónimo no puede aceptar valores nulos devueltos por la consulta del marco de la entidad?

Cuando bash ejecutar la siguiente consulta de Entity Framework:

var l = (from s in db.Samples let action = db.Actions.Where(x => s.SampleID == x.SampleID && x.ActionTypeID == 1).FirstOrDefault() where s.SampleID == sampleID select new { SampleID = s.SampleID, SampleDate = action.ActionDate, }).ToList(); 

Me sale la siguiente excepción:

La conversión al tipo de valor ‘DateTime’ falló porque el valor materializado es nulo. El parámetro genérico del tipo de resultado o la consulta deben usar un tipo que pueda contener nulos.

El problema probablemente es que Action.ActionDate se define como DateTime no anulable en el modelo EF, pero la consulta devuelve un null cuando no hay acciones relevantes asignadas a Sample .

La solución es devolver un tipo no anónimo con propiedades anulables, pero ¿por qué el tipo anónimo no puede aceptar el resultado nulo? ¿Se puede forzar de alguna manera que se cree el tipo anónimo con propiedades anulables?

Está utilizando tipos anónimos, no tipos generics. Los tipos anónimos son definidos por el comstackdor en tiempo de comstackción. Al final es como si hubieras creado un

 class MyEntity { public readonly int SampleID; public readonly DateTime SampleDate; } 

Los tipos son “seleccionados” por el comstackdor en función de los tipos que usa a la derecha de = en el new . Entonces, si SampleID es int y ActionDate es DateTime entonces se usarán esos tipos.

Ahora, lo que sucede es que cuando Entity Framework ejecuta la consulta y “deserializa” los datos en la clase ” MyEntity “, intenta convertir el null recibido por el SQL en un DateTime , y la conversión falla. La solución es definir el ActionDate como DateTime? en el tipo anónimo:

 SampleDate = (DateTime?)action.ActionDate, 

o para dar un valor a SampleDate cuando ActionDate es null :

 SampleDate = (DateTime?)action.ActionDate ?? default(DateTime), 

(esta segunda solución no se ha probado porque no tengo un servidor SQL cerca de mí, si funciona, SampleDate será DateTime y contendrá la fecha devuelta por la consulta o DateTime.MinValue cuando la fecha sea null )