为什么匿名类型实例不能接受实体框架查询返回的空值?

Voj*_*nal 2 c# entity-framework anonymous-types

当我尝试运行以下实体框架查询时:

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();
Run Code Online (Sandbox Code Playgroud)

我得到以下异常:

转换为值类型 'DateTime' 失败,因为具体化值为 null。无论哪种结果类型的泛型参数或查询必须使用可空类型。

问题可能是在 EF 模型中Action.ActionDate被定义为不可为空DateTime,但是null 当没有分配给 的相关操作时查询返回Sample

解决方法是返回一个具有可为空属性的非匿名类型,但为什么匿名类型不能接受空结果呢?匿名类型可以以某种方式强制创建为可空属性吗?

xan*_*tos 5

您使用的是匿名类型,而不是泛型类型。匿名类型由编译器在编译时定义。最后就像你创造了一个

class MyEntity
{
    public readonly int SampleID;
    public readonly DateTime SampleDate;
}
Run Code Online (Sandbox Code Playgroud)

类型由编译器根据您=new. 因此,如果 SampleID 是int并且ActionDate是,DateTime那么将使用这些类型。

现在,当实体框架执行查询并“反序列化”“ MyEntity”类中的数据时,它会尝试将nullSQL 接收到的数据转换为 a DateTime,并且转换失败。解决方法是在匿名类型中定义ActionDate为 a DateTime?

SampleDate = (DateTime?)action.ActionDate,
Run Code Online (Sandbox Code Playgroud)

SampleDateActionDate是时给出一个值null

SampleDate = (DateTime?)action.ActionDate ?? default(DateTime),
Run Code Online (Sandbox Code Playgroud)

(这第二种解决方案是未经检验的,因为我没有一个SQL Server的靠近我,如果它的工作SampleDate将是一个DateTime,将包含由查询或返回的日期DateTime.MinValue时,日期是null