C# EF生成的SQL查询在查询datetime列时返回空结果,但该记录存在于数据库中

C# EF生成的SQL查询在查询datetime列时返回空结果,但该记录存在于数据库中,c#,.net,sql-server,entity-framework,datetime,C#,.net,Sql Server,Entity Framework,Datetime,我有一个非常简单的SQL Server数据库表,其中包含datetime主键: 我为此表生成了EF模型和数据库上下文: [表格测试] 公共部分类测试 { 公共日期时间Id{get;set;} 公共int值{get;set;} } 公共部分类模型:DbContext { 公共模型:basename=Model{} 公共虚拟数据库集测试{get;set;} ModelCreatingDBModelBuilder modelBuilder{}上的受保护重写无效 } 试验表中有一条Id=2016-09-

我有一个非常简单的SQL Server数据库表,其中包含datetime主键:

我为此表生成了EF模型和数据库上下文:

[表格测试] 公共部分类测试 { 公共日期时间Id{get;set;} 公共int值{get;set;} } 公共部分类模型:DbContext { 公共模型:basename=Model{} 公共虚拟数据库集测试{get;set;} ModelCreatingDBModelBuilder modelBuilder{}上的受保护重写无效 } 试验表中有一条Id=2016-09-21 15:20:01.003的记录。让我们尝试使用EF上下文读取该记录:

var data=context.Test 其中o=>o.Id==新日期时间2016,09,21,15,20,01,003 托利斯特先生; Console.WriteLinedata.Count;//这里的data.Count=0! 即使具有此ID的数据库记录存在,EF也返回0个记录。这是生成的EF SQL查询:

-此查询生成一个空结果 选择 [Extent1].[Id]作为[Id], [Extent1].[Value]作为[Value] 从[dbo].[Test]到[Extent1] 其中convertdatetime2,'2016-09-21 15:20:01.0030000',121=[Extent1].[Id] 如您所见,EF将DateTime值从Where方法谓词转换为datetime2 SQL类型。实际上,这个查询返回一个空的结果集

如果删除转换并更改日期以匹配datetime类型格式,即删除尾随的零,则查询将按预期工作:

-此查询返回现有记录 选择 [Extent1].[Id]作为[Id], [Extent1].[Value]作为[Value] 从[dbo].[Test]到[Extent1] 其中[Extent1].[Id]='2016-09-21 15:20:01.003'
我知道将我的Id列的类型更改为datetime2实际上可以解决这个问题,Microsoft使用datetime2进行所有新的开发。但我仍然很好奇,这种行为是bug还是实体框架中的设计?有没有一种方法可以使它与datetime底层SQL类型一起工作?

是的,这是通过设计实现的

原因:如果没有为datetime字段设置任何值,则EF将发送1.1.0001作为默认值。无法使用SQL datetime类型处理该值。这就是为什么EF团队建议在SQL server上使用datetime2作为数据类型的原因


EF的最新版本EF core不支持SQL Server 2005,但它支持2008年及以后的版本。原因与我前面提到的相同。换句话说,SQL server 2005上没有datetime2数据类型

首先,虽然DateTime适合用作索引,但不建议将其用作主键。其次,您可以尝试设置属性类型以避免转换:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Test>()
        .Property(m => m.Id)
        .HasColumnType("datetime");
}

您可能应该避免将各种数据库上的float和real作为表上的主键来表示float或real日期时间。您没有可移植性,并且经常会遇到类似的问题。只是尝试了HasColumnTypedatetime,它不会影响生成的SQL查询-结果仍然为空。但这一事实如何阻止EF为datetime数据类型生成正确的查询?B'cos EF只知道datetime2。这就是它尝试将其转换为datetime2的原因。这是设计的。