如何在 LINQ to 实体表达式中使用 CreateDateTime

Ger*_*hes 4 .net c# linq entity-framework

因为如果您尝试在 LINQ 表达式中使用 DateTime,您将得到:

Only parameterless constructors and initializers are supported in LINQ to Entities.

最好的方法是使用DbFunctions.CreateDateTime Methodhttps://msdn.microsoft.com/en-us/library/dn218443 (v=vs.113).aspx

不工作示例:

await ctx.Example.AsNoTracking()
    .Where(e => e.Id == id)
    .Select(e => new EducationDTO {
            StartDate =  new DateTime(e.StartDate, 1, 1)
            EndDate = new DateTime(e.EndDate, 1, 1)
    })
    .ToListAsync().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)

尝试示例:

await ctx.Example.AsNoTracking()
    .Where(e => e.Id == id)
    .Select(e => new EducationDTO {
            StartDate =  DbFunctions.CreateDateTime(e.StartDate, 1, 1, null, null, null) ?? DateTime.Now,
            EndDate = DbFunctions.CreateDateTime(e.EndDate, 1, 1, null, null, null) ?? DateTime.Now,
    })
    .ToListAsync().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)

在我尝试使用CreateDateTime示例时,CreateDatetime 将为 null,我只会得到DateTime.Now.

我究竟做错了什么?

Iva*_*oev 5

假设非工作示例是正确的(即e.StartDate/e.EndDateint并代表年份),唯一的问题是不支持的DateTime构造函数。

正如您所提到的,正确的方法DbFunctions.CreateDateTime具有以下签名:

public static Nullable<DateTime> CreateDateTime(
    Nullable<int> year,
    Nullable<int> month,
    Nullable<int> day,
    Nullable<int> hour,
    Nullable<int> minute,
    Nullable<double> second
)
Run Code Online (Sandbox Code Playgroud)

文档中没有提到(尽管这是典型的数据库表达式行为),结果是null任何参数为null. 这也意味着,如果所有参数都不...... null - 事实上,结果并不好null

因此,您的场景中的正确用法如下:

.Select(e => new EducationDTO {
        StartDate = DbFunctions.CreateDateTime(e.StartDate, 1, 1, 0, 0, 0).Value,
        EndDate = DbFunctions.CreateDateTime(e.EndDate, 1, 1, 0, 0, 0).Value,
})
Run Code Online (Sandbox Code Playgroud)