it-swarm.com.de

Die Konvertierung eines Datentyps datetime2 in einen Datentyp datetime führt zu einem Wert außerhalb des Bereichs

Ich habe eine Datentabelle mit 5 Spalten, in der eine Zeile mit Daten gefüllt und dann über eine Transaktion in der Datenbank gespeichert wird.

Beim Speichern wird ein Fehler zurückgegeben:

Die Konvertierung eines datetime2-Datentyps in einen datetime-Datentyp führte zu einem Wert außerhalb des Bereichs

Es impliziert, wie gelesen, dass meine Datentabelle einen Typ von DateTime2 Hat und meine Datenbank ein DateTime; das ist falsch.

Die Datumsspalte ist wie folgt auf DateTime gesetzt:

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

Frage

Kann dies im Code gelöst werden oder muss auf Datenbankebene etwas geändert werden?

347
Gerbrand

Welche Art von Daten haben Sie in der Spalte?

Passen alle in den Bereich des Typs?


Abgesehen davon ist der richtige Weg, um ein Type -Objekt für den DataColumn -Konstruktor zu erhalten, das typeof -Schlüsselwort, das um Größenordnungen schneller ist.

Um die Spalte zu erstellen, sollten Sie daher schreiben

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

Dies kann passieren, wenn Sie einem DateTime -Feld keinen Wert zuweisen, wenn das Feld nicht akzeptiert [~ # ~] null [~ # ~] Werte.

Das hat es für mich behoben!

696
andyuk

Sowohl das DATETIME als auch das DATETIME2 Karte zu System.DateTime in .NET - Sie können eine "Konvertierung" nicht wirklich durchführen, da es sich wirklich um denselben .NET-Typ handelt.

Siehe die MSDN-Dokumentseite: http://msdn.Microsoft.com/en-us/library/bb675168.aspx

Es gibt zwei verschiedene Werte für "SqlDbType" für diese beiden - können Sie diese in Ihrer DataColumn -Definition angeben?

ABER: Unter SQL Server unterscheidet sich der unterstützte Datumsbereich erheblich.

DATETIME unterstützt 1753/1/1 bis "Ewigkeit" (9999/12/31), während DATETIME2 unterstützt 0001/1/1 bis in alle Ewigkeit.

Sie müssen also wirklich nach dem Jahr des Datums suchen - wenn es vor 1753 liegt, müssen Sie es NACH 1753 in etwas ändern, damit die Spalte DATETIME in SQL Server damit umgehen kann.

Marc

150
marc_s

In meiner SQL Server 2008-Datenbank hatte ich eine DateTime -Spalte, die als nicht nullwertfähig markiert war, aber eine GetDate() -Funktion als Standardwert. Beim Einfügen eines neuen Objekts mit EF4 trat dieser Fehler auf, weil ich keine DateTime-Eigenschaft für mein Objekt explizit übergeben habe. Ich hatte erwartet, dass die SQL-Funktion das Datum für mich verarbeiten würde, aber das war nicht der Fall. Meine Lösung bestand darin, den Datumswert aus dem Code zu senden, anstatt sich auf die Datenbank zu verlassen, um ihn zu generieren.

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

für mich war es, weil das datetime war ..

01/01/0001 00:00:00

in diesem Fall möchten Sie Ihrem EF DateTime-Objekt den Wert null zuweisen. Verwenden Sie dazu meinen FirstYearRegistered-Code als Beispiel

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

Manchmal weiß EF nicht, dass es sich um eine berechnete Spalte oder einen Trigger handelt . Standardmäßig legen diese Vorgänge nach einer Einfügung einen Wert außerhalb von EF fest.

Der Fix besteht darin, Computed in EFs edmx für diese Spalte in der Eigenschaft StoreGeneratedPattern anzugeben.

Für mich war es, als die Spalte einen Auslöser hatte, der das aktuelle Datum und die aktuelle Uhrzeit einfügte, siehe unten im dritten Abschnitt.


Schritte zum Auflösen

Öffnen Sie in Visual Studio die Seite Model Browser Und dann Model und dann Entity Types ->

  1. Wählen Sie die Entität und die Datum-Zeit-Eigenschaft aus
  2. Wählen Sie StoreGeneratedPattern
  3. Auf Computed setzen

EF Model Browser Model Entity Type dialog


In diesem Fall sind andere Antworten Problemumgehungen. In der Spalte muss zum Zeitpunkt der Erstellung des Datensatzes eine Uhrzeit und ein Datum angegeben werden. Dies ist die Aufgabe von SQL, einen Trigger auszuführen, um die richtige Uhrzeit hinzuzufügen. So wie dieser SQL-Trigger:

DEFAULT (GETDATE()) FOR [DateCreated].

20
ΩmegaMan

Dieser hat mich verrückt gemacht. Ich wollte die Verwendung einer nullbaren Datumszeit (DateTime?) Vermeiden. Ich hatte auch keine Möglichkeit, den Typ datetime2 Von SQL Server 2008 zu verwenden

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

Ich habe mich schließlich für Folgendes entschieden:

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;
                    }
                }
            }
        }
    }
}
19
sky-dev

Ich bin darauf gestoßen und habe Folgendes zu meiner datetime-Eigenschaft hinzugefügt:

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

Wenn wir kein Feld Datum Zeit zu Datum Zeit übergeben, wird das Standarddatum {01.01.10001, 00:00 Uhr} übergeben.

Dieses Datum ist jedoch nicht mit der Entity-Frame-Arbeit kompatibel. Daher wird Die Konvertierung eines datetime2-Datentyps in einen datetime-Datentyp führte zu einem Wert außerhalb des gültigen Bereichs

Gerade default DateTime.now in das Datumsfeld, wenn Sie kein Datum übergeben.

movie.DateAdded = System.DateTime.Now
9
Lijo

Am einfachsten ist es, Ihre Datenbank so zu ändern, dass datetime2 anstelle von datetime verwendet wird. Die Kompatibilität funktioniert gut und Sie werden keine Fehler bekommen.

Sie werden immer noch ein paar Tests machen wollen ...

Der Fehler liegt wahrscheinlich daran, dass Sie versuchen, ein Datum auf das Jahr 0 oder so zu setzen - aber alles hängt davon ab, wo Sie die Kontrolle haben, um Dinge zu ändern.

6
Rob Farley

Ich habe diesen Beitrag gefunden, um herauszufinden, warum ich immer wieder den folgenden Fehler erhalte, der durch die anderen Antworten erklärt wird.

Die Konvertierung eines datetime2-Datentyps in einen datetime-Datentyp führte zu einem Wert außerhalb des Bereichs.

Verwenden Sie ein nullwertfähiges DateTime-Objekt.
public DateTime? PurchaseDate {get; einstellen; }

Wenn Sie das Entity Framework verwenden Setzen Sie die Eigenschaft nullable in der edmx-Datei auf True

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

4
stink

Wie andyuk bereits erwähnt hat, kann dies passieren, wenn ein [~ # ~] null [~ # ~] Wert einem nicht nullierbaren zugewiesen wird. -DateTime Feld. Ziehen Sie in Betracht, DateTime in DateTime? oder Nullable < DateTime> zu ändern. Beachten Sie, dass bei Verwendung einer Abhängigkeitseigenschaft auch sichergestellt sein sollte, dass der Typ Ihrer Abhängigkeitseigenschaft ebenfalls ein nullwertfähiger DateTime-Typ ist.

Nachfolgend finden Sie ein Beispiel aus der Praxis für eine unvollständige DateTime bis DateTime? Typanpassung, die das ungerade Verhalten hervorruft

enter image description here

3
Julio Nobre

Das Entity Framework 4 arbeitet mit dem Datentyp datetime2, sodass in db das entsprechende Feld für SQL Server 2008 datetime2 sein muss.

Um die Lösung zu erreichen, gibt es zwei Möglichkeiten.

  1. Um den datetime-Datentyp in Entity Framwork 4 zu verwenden, müssen Sie das ProviderManifestToken in der edmx-Datei auf "2005" setzen.
  2. Wenn Sie das entsprechende Feld auf Null zulassen setzen (es konvertiert es in NULLABLE), verwendet EF automatisch Datumsobjekte als Datum/Uhrzeit.
2
Mahmut C

Erstellt eine Basisklasse basierend auf der Implementierung von @ sky-dev. Dies kann also problemlos auf mehrere Kontexte und Entitäten angewendet werden.

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;
                    }
                }
            }
        }
    }
}

Verwendungszweck:

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

Manchmal funktioniert es gut auf Entwicklungsmaschinen und nicht auf Servern. In meinem Fall musste ich sagen:

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

In der Datei web.config.

Die Zeitzone auf dem Computer (Server) stimmte (mit der Ländereinstellung des CO) überein, die Web-App jedoch nicht. Diese Einstellung wurde vorgenommen und es hat wieder funktioniert.

Natürlich hatten alle Daten Wert.

: D

Ich bin mir dieses Problems bewusst und Sie alle sollten es auch sein:

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

In SQL wurde ein neuer Feldtyp erstellt, um dieses Problem zu vermeiden (datetime2).

Dieser Feldtyp 'Datum' hat dieselben Bereichswerte wie eine DateTime .Net-Klasse. Es wird all Ihre Probleme lösen, daher denke ich, dass der beste Weg, dies zu lösen, darin besteht, den Typ Ihrer Datenbankspalte zu ändern (Ihre Tabellendaten werden dadurch nicht beeinflusst).

0
marcolomew

In meinem Fall haben wir ein Datum auf eine Datumszeit übertragen und haben diesen Fehler erhalten. Was passiert ist, dass Date ein "programmiererorientierteres" Minimum von 01/01/0001 hat, während Datetime bei 1753 steckt

Kombinieren Sie dies mit einem Datenerfassungsfehler von unserer Seite, und Sie bekommen Ihre Ausnahme!

0
Chris

Überprüfen Sie die folgenden beiden Punkte: 1) Dieses Feld hat keinen NULL-Wert. Zum Beispiel:

 public DateTime MyDate { get; set; }

Ersetzen:

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

2) Neu die Datenbank wieder. Zum Beispiel:

db=new MyDb();
0
MSM19

Das Hinzufügen dieses Codes zu einer Klasse in ASP.NET hat für mich funktioniert:

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