gpt4 book ai didi

sql-server - Entity Framework 7 无法插入日期时间

转载 作者:可可西里 更新时间:2023-11-01 13:53:30 27 4
gpt4 key购买 nike

我正在使用 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 呈现的类型和值的区别:

Windows

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 上的失败是:

Conversion failed when converting date and/or time from character string.

问题

  1. 当类型明确设置为 datetime 时,为什么 Windows 会生成 datetime2
  2. Linux 版本正在生成无效的 SQL,因此失败。如何在 mono/linux 上插入 datetime 值?

最佳答案

  1. .NET DateTime 类型比 sql server 的“datetime”类型范围更广。实际上,.NET DateTime 与 sql server 的“datetime2”类型具有相同的范围,这就是为什么 Entity Framework 在将 DateTime 转换为 sql 日期(如您的示例)时将在任何地方使用 datetime2(如果可能)。在这种情况下,表列的类型无关紧要。你可以阅读这个design meeting notes其中 EF 团队讨论了 datetime 和 datetime2 的问题并决定保持原样(以及背后的原因)。

  2. Mono 使用 TDS 与 sql server 一起工作(基于 FreeTDS ,它使用的是相当过时的版本。这个版本不知道 sql server 的“datetime2”类型,所以没有升级到新版本的 TDS(也许现在工作量太大),实现了某种 hack,将 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

    您可以阅读更多相关信息 here .

您可能会问是否可以在 mono 上将 EF 与 sql server 一起使用。那么,您可以通过在 EF 模型中将 ProviderManifestToken 设置为 2005 来解决问题。这将使 EF 与 sql server 2005 一起工作,并且不会在所有地方使用 datetime2。但是您显然会丢失在 sql server 2005 之后添加的其他类型,更不用说那是肮脏的 hack。

作为旁注 - 最好不要使用 sql server 在 mono 上做任何严肃的开发。 mono 中的 SQL 服务器提供程序充满了错误,上面的错误是最无辜的错误之一。它有空值问题,连接池问题(这个问题非常严重——如果你在连接池连接上超时——这个连接将在整个生命周期内中断,并且对该连接的所有查询都将失败. Hack - 如果您的查询在连接池上超时,则从连接池中删除连接)等。大多数此类错误已为人所知多年,但仍未修复。如果您有选择 - 只需使用 postgresql,它是免费的,很好,而且我在单声道上没有遇到任何问题。

关于sql-server - Entity Framework 7 无法插入日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32833879/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com