2017-07-18 67 views
0

レコードを取得するためにEntity Frameworkを使用していますが、フィルタの1つはdatetimeです。DateTimeの比較時にEntity Frameworkでdatetime2の代わりにdatetimeが使用されるようにするにはどうすればよいですか?

それは、このようなクエリを生成:

([Extent1].[TxnDateTime] >= convert(datetime2, '2015-02-21 00:00:00.0000000', 121)) 
AND ([Extent1].[TxnDateTime] <= convert(datetime2, '2017-02-21 23:59:59.9999999', 121)) 

私はEFがdatetime代わりのdatetime2に変換することができます方法はありますか?はるかに速いようです。

私はEFがこれを生成したい:

[Extent1].[TxnDateTime] >= convert(datetime, '21/02/2015') 
AND [Extent1].[TxnDateTime] <= convert(datetime, '21/02/2017') 

datetimeで:

CPU時間= 1234ミリ秒、経過時間= 1250ミリ秒。 datetime2

CPU時間= 1625秒、経過時間= 1645秒。

.NET DateTimeタイプがSQL Server datetime2にマップされていることを理解しています。私のオプションは何ですか?

列はNULL可能datetimeであり、私は興味深いDateTime?

+2

エンティティとスキーマの設定方法、実行中のクエリ、使用しているデータベース/バージョンを拡張できますか? DateTime .NetプロパティタイプのSQL ServerとDateTimeの列型に直面すると、次のようになります。convert(datetime2 '2016-07-01 00:00:00.0000000'、121)= [Extent1] 。[TxnDateTime]データベース列で余分な変換が発生していません。あなたが文字列に変換してからDateTime2に戻るという事実は、あなたの列とプロパティマッピングの間に何か不思議なことがあることを暗示しているようです。 –

+0

あなたが正しいです、私が使用した関数、 'TruncateTime'によって変換が行われました。私はそれを削除することができた、私の質問を更新します。 –

+0

エンティティ間でEFクエリを実行し、DateTime値の範囲で検索すると、DateTime2とDateTimeの変換のパフォーマンスはほとんど無視できます。私は、クエリとCPUコストの両方のセットでプロファイラを実行しました。有効期間は事実上同一でした。 (ときどきdatetime2のほうが多少高価でしたが、時々datetimeの実行にはコストがかかりました(1回の実行につき100k行以上の50ms以内)。私はあなたが観察したかもしれないパフォーマンスがtruncate関数によるものだと考えています –

答えて

1

うーん、それを比較しています! DateTime列のテーブルを持つ単純なデータベースモデルを作成すると、Entity Frameworkは既定でDateTime2ではなくSQL DateTime型の列を作成します。私はEntityFrameworkバージョン6.1.3

class Blog 
{ 
    public int Id {get; set;} 
    public DateTime IntroductionDate {get; set;} 
} 

SQL Server Management Studioを列IntrdductionDateプロパティ(datetime, not null)を持っていることを報告しました。

とにかく、私は、すべてのDateTimeをdateTime2としてモデル化し、datetimeの代わりにしたいという問題がありました。私はあなたがあなたがモデリングしたいすべてのタイプのためにこれを使用することができますdatetime

class MyDbContext : DbContext 
{ 
    DbSet<...> ... 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Configure that all used DateTime should be modeled datetime2: 
     const string standardDateTimeType = "datetime2"; 
     modelBuilder.Properties<DateTime>() 
      .Configure(p => p.HasColumnType(standardDateTimeType); 
     ... 
    } 

を使用するように列を強制的に同様の方法を使用することができますね。たとえばあなたはすべての小数は、同じ精度とスケールを持っていることをモデル化する場合:

byte standardDecimalPrecision = 19; 
byte standardDecimalScale = 8; 
modelBuilder.Properties<decimal>() 
    .Configure(p => p.HasPrecision(standardDecimalPrecision, standardDecimalScale)); 

もちろん、あなたがColumnAttributeデータアノテーションを使用して列の型を設定できますが、それは、すべてのDateTimeのためにこれを行うためにあなたを強制します将来のクラスがこれを忘れる可能性のあるエラーを伴います。