web-dev-qa-db-ja.com

datetime2データ型からdatetimeデータ型への変換の結果、範囲外の値

私は5つの列を持つデータテーブルを持っています、そこで行はデータでいっぱいにされていてそれからトランザクションを通してデータベースに保存されています。

保存中にエラーが返されます。

Datetime2データ型をdatetimeデータ型に変換した結果、値が範囲外になりました

読んだように、私のdatatableはDateTime2の型を持ち、私のデータベースはDateTimeを持ちます。それは間違いです。

Dateカラムは次のようにDateTimeに設定されています。

new DataColumn("myDate", Type.GetType("System.DateTime"))

質問

これはコードで解決できますか、それともデータベースレベルで何か変更する必要がありますか?

336
Gerbrand

コラムにはどのような日程がありますか。

それらのすべてがタイプの範囲内に収まりますか?


余談ですが、TypeコンストラクタのDataColumnオブジェクトを取得する正しい方法は、typeofキーワードです。これは桁違いに高速です。

したがって、列を作成するには、次のように書く必要があります。

new DataColumn("myDate", typeof(DateTime))
52
SLaks

これは、フィールドが受け入れないときにDateTimeフィールドに値を割り当てないと発生する可能性があります。 NULLの値。

それは私のためにそれを修正しました!

684
andyuk

DATETIMEDATETIME2はどちらも.NETのSystem.DateTimeにマップします。実際には同じ.NET型なので、「変換」はできません。

MSDNのドキュメントページを参照してください。 http://msdn.Microsoft.com/ja-jp/library/bb675168.aspx

これら2つの "SqlDbType"には2つの異なる値があります。DataColumnの定義でそれらを指定できますか?

しかし、SQL Serverでは、サポートされている日付範囲はまったく異なります。

DATETIMEは1753/1/1から "eternity"(9999/12/31)までをサポートしていますが、DATETIME2は0001/1/1からeternityまでをサポートしています。

そのため、本当に必要なのは日付の年をチェックすることです - 1753年より前の場合は、SQL ServerのDATETIME列で処理するために、1753年以降に変更する必要があります。

マーク

148
marc_s

私のSQL Server 2008データベースでは、null値ではないとしてフラグ付けされたDateTimeカラムを持っていましたが、デフォルト値としてGetDate()関数がありました。 EF4を使用して新しいオブジェクトを挿入するときに、オブジェクトのDateTimeプロパティを明示的に渡していないため、このエラーが発生しました。 SQL関数が日付を処理すると思っていましたが、処理しませんでした。私の解決策はそれを生成するためにデータベースに頼るのではなくコードから日付の値を送ることでした。

obj.DateProperty = DateTime.now; // C#
40
Graham

私にとっては、日時が..だったからでした。

01/01/0001 00:00:00

この場合、あなたはあなたにnullを代入したいですEF DateTime Object ...例として私のFirstYearRegisteredコードを使って

DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
    vehicleData.DateFirstReg = FirstYearRegistered;
}  
28
JGilmartin

EFは、それが計算列またはトリガーを処理していることを知らないことがあります。設計上、これらの操作は挿入後にEFの範囲外の値を設定します。

この問題を解決するには、Computedプロパティのその列に対してEFのedmxStoreGeneratedPatternを指定します。

私にとっては、列に現在の日付と時刻を挿入するトリガーがあるときでした。下記の3番目のセクションを参照してください。


解決するためのステップ

Visual StudioでModel Browserページを開き、次にModelを開き、次にEntity Types - > thenを開きます。

  1. エンティティと日時プロパティを選択します。
  2. StoreGeneratedPatternを選択してください
  3. Computedに設定

EF Model Browser Model Entity Type dialog


このような状況で他の答えは回避策です、列の目的はレコードが作成されたときに指定された時間/日付を持つことであり、それは正しい時間を追加するためにトリガーを実行するSQLの仕事です。このSQLトリガのように:

DEFAULT (GETDATE()) FOR [DateCreated]

19
ΩmegaMan

これは私を夢中にさせていました。 NULL可能な日付時刻(DateTime?)の使用を避けたいと思いました。 SQL Server 2008のdatetime2型を使う選択肢もありませんでした

modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");

私は結局次のことを選んだ。

public class MyDb : DbContext
{
    public override int SaveChanges()
    {
        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<MyEntityBaseClass>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}
18
sky-dev

私はこれに遭遇し、私のdatetimeプロパティに以下を追加しました:

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }
9
Rogala

日付時刻フィールドに日付時刻を渡さないと、デフォルトの日付{1/1/0001 12:00:00 AM}が渡されます。

しかし、この日付はエンティティフレームワークと互換性がないため、datetime2データ型からdatetimeデータ型への変換がスローされ、範囲外の値になります

日付を渡さない場合は、日付フィールドにdefault DateTime.nowを入力してください。

movie.DateAdded = System.DateTime.Now
9
Lijo

最も簡単な方法は、datetimeの代わりにdatetime2を使用するようにデータベースを変更することです。互換性はうまく機能し、そしてあなたはあなたのエラーを得ることはありません。

あなたはまだテストの束をしたいと思うでしょう...

エラーはおそらくあなたが0年か何かに日付を設定しようとしていることが原因です - しかしそれはすべてあなたがものを変更するための制御権を持っている場所に依存します。

6
Rob Farley

私はなぜ私が他の答えによって説明される以下の誤りを得続けたか理解しようとしているこのポストを見つけました。

datetime2データ型をdatetimeデータ型に変換すると、範囲外の値になりました。

NULL可能なDateTimeオブジェクトを使用します。
公開日時? PurchaseDate {get;セット; }

エンティティフレームワークを使用している場合edmxファイルのnull許容プロパティをTrueに設定します。

Set the nullable property in the edmx file to **True**

4
stink

andyuk がすでに指摘しているように、これはNULLの値がnonに割り当てられている場合に起こります。 NULL可能DateTimeフィールド。 DateTimeDateTime?またはNULL可能<DateTimeに変更することを検討してください。 >。 依存関係プロパティ を使用している場合は、依存関係プロパティの型もNULL可能なDateTime型であることを確認してください。

以下は不完全なDateTimeからDateTime?への型調整の実際の例です。

enter image description here

3
Julio Nobre

Entity Framework 4はdatetime2データ型を処理するため、dbではSQL Server 2008の対応するフィールドはdatetime2である必要があります。

解決策を実現するには2つの方法があります。

  1. Entity Framwork 4で日時データ型を使用するには、edmxファイルのProviderManifestTokenを "2005"に切り替える必要があります。
  2. 対応するフィールドをAllow Null(NULLABLEに変換)に設定した場合、EFは自動的にdateオブジェクトをdatetimeとして使用します。
2
Mahmut C

@ sky-dev実装に基づいて基本クラスを作成しました。そのため、これは複数のコンテキストやエンティティに簡単に適用できます。

public abstract class BaseDbContext<TEntity> : DbContext where TEntity : class
{
    public BaseDbContext(string connectionString)
        : base(connectionString)
    {
    }
    public override int SaveChanges()
    {

        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<TEntity>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}

使用法:

public class MyContext: BaseDbContext<MyEntities>
{

    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    public MyContext()
        : base("name=MyConnectionString")
    {
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    /// <param name="connectionString">The connection string.</param>
    public MyContext(string connectionString)
        : base(connectionString)
    {
    }

     //DBcontext class body here (methods, overrides, etc.)
 }
1
C0r3yh

時にはそれは開発マシンではなくサーバーではうまく動作します。私の場合は、次のように書きました。

<globalization uiCulture="es" culture="es-CO" />

Web.configファイル内。

マシン(サーバー)のタイムゾーンは(COロケールに対して)正しいのですが、Webアプリは正しくありませんでした。この設定は完了し、それは再びうまくいきました。

もちろん、すべての日付に価値がありました。

:D

私はこの問題を認識しており、皆さんもそうすべきです:

https://en.wikipedia.org/wiki/Year_2038_problem

SQLでは、この問題を回避するために新しいフィールドタイプが作成されました(datetime2)。

この「日付」フィールドタイプには、DateTime .Netクラスと同じ範囲値があります。それはすべての問題を解決するので、それを解決する最良の方法は、データベースの列タイプを変更することだと思います(テーブルデータには影響しません)。

0
marcolomew

私の場合は、DateをDatetimeにキャストしていましたが、このエラーが発生しました。 Datetimeは1753に固定されていますが、Dateには "プログラマより指向"の最小01/01/0001があります

私たちの側でデータ収集エラーとそれを組み合わせると、あなたはあなたの例外を得ます!

0
Chris

次の2つを確認してください。1)このフィールドにはNULL値がありません。例えば:

 public DateTime MyDate { get; set; }

置換先:

public DateTime MyDate { get; set; }=DateTime.Now;

2)データベースを再度新規作成します。例えば:

db=new MyDb();
0
MSM19

このコードをASP.NETのクラスに追加することは私にとっては大変でした。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
}
0
Howie Krauth