entity framework7无法插入date时间

我正在使用EntityFramework 7,beta7并具有以下实体:

C#

public class Log { [Column(TypeName ="datetime")] public DateTime Date { get; set; } ... } 

SQL

 CREATE TABLE [dbo].[Logs] ( [Date] [datetime] NOT NULL, ... ) 

我执行以下操作:

 db.Logs.Add(new Log { Date = DateTime.UtcNow }); db.SaveChanges(); 

这在Windows上是成功的,但在debian单声道失败。 相同的SQL服务器/数据库。 下面是生成的SQL。 请注意@p1呈现的types和值的差异:

视窗

 exec sp_executesql N'SET NOCOUNT OFF; INSERT INTO [Logs] ([Browser], [Date], [Exception], [HostAddress], [Level], [Logger], [Message], [Thread], [Url], [Username]) OUTPUT INSERTED.[Id] VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9); ',N'@p0 nvarchar(max) ,@p1 datetime2(7),@p2 nvarchar(max) ,@p3 nvarchar(max) ,@p4 nvarchar(4000),@p5 nvarchar(4000),@p6 nvarchar(4000),@p7 nvarchar(4000),@p8 nvarchar(max) ,@p9 nvarchar(max) ',@p0=NULL,@p1='2015-09-28 23:02:26.0367851',@p2=NULL,@p3=NULL,@p4=N'INFO',@p5=N'Fanatics.ConsoleApp.Program',@p6=N'Console app test',@p7=N'0',@p8=NULL,@p9=NULL go 

Linux的

 exec sp_executesql N'SET NOCOUNT OFF; INSERT INTO [Logs] ([Browser], [Date], [Exception], [HostAddress], [Level], [Logger], [Message], [Thread], [Url], [Username]) OUTPUT INSERTED.[Id] VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9); ',N'@p0 nvarchar(4000), @p1 char(27), @p2 nvarchar(4000), @p3 nvarchar(4000), @p4 nvarchar(4000), @p5 nvarchar(4000), @p6 nvarchar(4000), @p7 nvarchar(4000), @p8 nvarchar(4000), @p9 nvarchar(4000)',@p0=NULL,@p1='2015-09-28T23:03:21.5561720',@p2=NULL,@p3=NULL,@p4=N'INFO',@p5=N'Fanatics.ConsoleApp.Program',@p6=N'Console app test',@p7=N'0',@p8=NULL,@p9=NULL go 

Linux上的故障是:

从string转换date和/或时间时转换失败。

问题

  1. 为什么Windows在datetime2types被明确设置为datetime时生成?
  2. linux版本正在生成无效的SQL,因此失败。 我怎样才能在mono / linux上插入datetime值?

  1. .NET DateTime类型比sql server的“datetime”类型有更广的范围。 实际上,.NET DateTime与sql server的“datetime2”类型具有相同的范围,这就是为什么实体框架在将DateTime转换为sql日期的任何地方都会使用datetime2(如果可能的话)(如你的例子)。 表格列的类型在这种情况下并不重要。 您可以阅读本设计会议记录 ,EF小组讨论datetime和datetime2问题,并决定保留原样(以及原因)。

  2. 单声道使用TDS与SQL服务器(基于FreeTDS ,它使用相当过时的版本,这个版本不知道关于SQL服务器的“日期时间2”类型,所以而不是升级到新版本的TDS(也许这是太多现在工作,类型的黑客实施,将\ datetime2从\转换为字符串。现在,datetime2具有比datetime更高的精度,所以当datetime2转换为字符串,然后将该字符串转换为datetime(这是隐式完成)看,这很容易检查:

     select cast('2015-09-28T23:03:21.5561720' as datetime2) -- < all fine select cast('2015-09-28T23:03:21.5561720' as datetime) -- < error from your question 

    你可以在这里阅读更多。

你可能会问,如果你可以在单声道的sql服务器上使用EF。 那么,你可以通过在EF模型中将ProviderManifestToken设置为2005来解决这个问题。 这将使EF工作与SQL server 2005,它不会使用datetime2到处。 但是你会失去其他类型的显然是在sql server 2005之后添加的,更不用说那是肮脏的破解了。

作为一个方面的说明 – 更好的不要做任何严重的发展与SQL server单声道。 单声道的sql服务器提供程序充满了bug,而上面的bug是最无辜的。 它有空值的问题,连接池的问题(这是一个非常严重的问题 – 如果你在连接池连接超时 – 这个连接将在整个生命周期中断, 所有在该连接上的查询将失败。如果你的查询超时了),等等。大多数这些错误是已知的多年,而不是固定的。 如果你有选择 – 只要使用postgresql,它是免费的,好,我没有在单声道的问题。