web-dev-qa-db-ja.com

Code-First Entity FrameworkおよびSQL ServerでのDateTimeプロパティの使用

サンプルクラスbookがあります:

public class Book
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateAdded { get; set; }
}

新しいbookBookDbコンテキストに追加しようとすると...

using (BookDb db = new BookDb())
{
    Book book = new Book {
        Name = "Some name",
        DateAdded = DateTime.Now
    };

    db.Books.Add(book);
    db.SaveChanges();
}

...エラーがスローされます:

System.Data.SqlClient.SqlException:datetime2データ型からdatetimeデータ型への変換の結果、値が範囲外になりました。ステートメントは終了されました。


この原因は、.NETとSQL Serverの間で互換性のないdatetime型であることがわかりました。 EFに従来のEntity FrameworkでSQL Serverの形式を使用するように指示する方法がありますが、どうすればCode-FirstEntityでできますかフレームワーク?

.NET 4(MVC 3 Webアプリ)およびSQL Server 2008 ExpressでEF4を使用しています。

27
Chad Levy

Fluent APIでタイプを指定できます。

_modelBuilder.Entity<Book>()
    .Property(f => f.DateTimeAdded)
    .HasColumnType("datetime2");
_

これにより、データベースにdatetime2(7)列が作成されます。精度を微調整する場合は、次を使用できます。

_modelBuilder.Entity<Book>()
    .Property(f => f.DateTimeAdded)
    .HasColumnType("datetime2")
    .HasPrecision(0);
_

... DBのdatetime2(0)列の場合。

ただし、datetime型では日付を1750年頃まで保存できるため、質問で示したコードは機能します。例外は以前の日付でのみ発生します。この例外の一般的な理由は、SQL ServerのDateTime列に格納できない年0001を表すため、初期化されていないdatetimeプロパティです。

データ注釈でこれを定義するための対応する属性はありません。 Fluent APIでのみ可能です。

48
Slauma

日付を保存する場合、値を設定する必要があります。そのため、このエラーが発生します。

DateTime?を使用してください。上記の魔法は必要ありません。

30
Houman

タイプdatetime2を使用して、クラスの属性に注釈を付けることができます。

public class Book
{
    [Column(TypeName = "datetime2")]
    public DateTime DateAdded { get; set; }
}
23
strangeoptics

移行が有効になっている場合は、すぐに調整することもできます。

public override void Up()
{
    CreateTable(
        "dbo.MyTable",
        c => new
        {
            Date = c.DateTime(false, 7, storeType: "datetime2"),
        });
}
2
cmxl