サンプルクラスbook
があります:
public class Book
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateAdded { get; set; }
}
新しいbook
をBookDb
コンテキストに追加しようとすると...
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を使用しています。
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でのみ可能です。
日付を保存する場合、値を設定する必要があります。そのため、このエラーが発生します。
DateTime?
を使用してください。上記の魔法は必要ありません。
タイプdatetime2を使用して、クラスの属性に注釈を付けることができます。
public class Book
{
[Column(TypeName = "datetime2")]
public DateTime DateAdded { get; set; }
}
移行が有効になっている場合は、すぐに調整することもできます。
public override void Up()
{
CreateTable(
"dbo.MyTable",
c => new
{
Date = c.DateTime(false, 7, storeType: "datetime2"),
});
}