Entity Framework 7がdatetimeを挿入できない

debian entity-framework-core mono sql-server windows

質問

私は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ではmonoで失敗する。同じ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での障害は次のとおりです。

文字列から日付および/または時刻を変換するときに変換に失敗しました。

質問

  1. なぜWindowsが発生しないdatetime2タイプが明示的に設定されている場合、 datetime
  2. Linux版では無効なSQLが生成されているため、失敗します。 mono / linuxにdatetime値を挿入するにはどうすればいいですか?

受け入れられた回答

  1. .NETのDateTime型は、SQL Serverの「datetime」型よりも広い範囲を持っています。実際には、.NET DateTimeはSQL Serverの「datetime2」型と同じ範囲にあります。そのため、Entity FrameworkはDateTimeをSQLの日付に変換するとき(可能な場合)、datetime2を使用します(例のように)。この場合、テーブル列のタイプは関係ありません。 EFチームがdatetimeとdatetime2の問題について議論し、これをそのままにしておくことを決めたこのデザインミーティングノートを読むことができます(その背後にある理由)。

  2. MonoはTDSを使ってSQL Server( FreeTDSをベースにしていますが 、かなり古いバージョンを使用しています)を使用します。このバージョンではSQL Serverの "datetime2"タイプについてはわかりませんので、 datetime2をdatetime2からstringに変換するようになりました。datetime2はdatetimeよりも精度が高いので、datetime2をstringに変換してから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に設定することで、回避策を講じることができます。これは、SQL Server 2005で動作するEFを作成し、どこでもdatetime2を使用しません。しかし、明らかにSQL Server 2005の後に追加された他のタイプは失われますが、それは汚いハックです。

副次的なこととして、SQL Serverでmonoを深刻に開発しない方がよいでしょう。モノのSqlサーバープロバイダにはバグがたくさんあり、上記のバグは最も無害です。それはヌル値、接続プールの問題(これは非常に深刻です - 接続プール接続でタイムアウトすると、この接続は生涯にわたって壊れ、その接続のすべてのクエリは失敗します)。あなたのクエリがタイムアウトした場合にプールするなど)。このバグのほとんどは何年も知られており、まだ修正されていません。選択肢があれば - ただpostgresqlを使ってください、それは無料でいいです。私はモノでそれに問題はありませんでした。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ