2013-03-01 6 views
38

Ich möchte txtBirthDate nicht validieren, also möchte ich DateTime.MinValue in der Datenbank übergeben.DateTime.MinValue und SqlDateTime Überlauf

Mein Code:

if (txtBirthDate.Text == string.Empty) 
    objinfo.BirthDate = DateTime.MinValue; 
else 
    objinfo.BirthDate = DateTime.Parse(txtBirthDate.Text); 

DateTime.MinValue Rückkehr Date = {1/1/0001 12:00:00 AM}

bekam ich einen SQL-Fehler:

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

Ich stehe es unter aber ich verstehe nicht, warum DateTime.MinValue Rückkehr ungültiges Datum Zeit welches nicht in die Datenbank eingefügt werden kann. Wie kann man mit dieser Art von Situation umgehen?

+0

definieren min-Wert zu erhalten? –

+1

Die Nachricht erklärt dir das irgendwie. Die vom SQL Server akzeptierte Mindestdatumszeit ist 1/1/1753, während .Net 1/1/0001 verwendet. Was verstehst Du nicht? –

+5

Die Logik würde empfehlen, 'DateTime?' In C# zu verwenden, dem Feld zu erlauben, null in der Datenbank zu akzeptieren und 'DBNull.Value' einzufügen, falls 'objinfor.BirthDate.HasValue'' false' ist. Was ich meine ist, dass es die Realität widerspiegeln sollte. Wenn eine Situation, in der es kein Geburtsdatum gibt, akzeptabel ist, sollte es nullfähig sein. – tpeczek

Antwort

70

Verwenden Sie DateTime.MinValue grundsätzlich nicht, um einen fehlenden Wert darzustellen. Sie können nicht Verwendung DateTime.MinValue in einem SQL Server-Datetime-Feld, wie SQL Server einen Minimalwert von Anfang an von 1753

Stattdessen haben, machen Sie Ihre BirthDate Eigenschaft ein Nullable<DateTime> (aka DateTime?), und setzen Sie sich auf null wenn du keinen Wert hast. Stellen Sie außerdem sicher, dass für Ihr Datenbankfeld keine Werte zulässig sind. Dann müssen Sie nur sicherstellen, dass null als NULL Wert in der Datenbank endet. Wie Sie das tun, hängt von Ihrem Datenzugriff ab, von dem Sie uns noch nichts erzählt haben.

+3

WCF nimmt automatisch 'DateTime.MinValue' an, wenn ein' DateTime' -Parameter zu Ihrem 'OperationContract' weggelassen wurde. Darüber hinaus akzeptiert WCF keine nullbaren Parameter. Was das bedeutet ist, dass Sie in jedem 'OperationContract' gezwungen sind, etwas wie 'if (myDate crush

+2

@crush: Nun, müssen Sie Ihr WCF-Modell und Ihr SQL-Modell direkt miteinander verbinden? Ich vermute, dass ich ein "logisches" Modell hätte, das eine "Nullable " hätte, und zu/von dem konvertieren würde, wenn ich WCF benutzen müsste. Nicht, dass ich WCF viel benutzt hätte, aber es fühlt sich wie eine schlechte Idee an, dass WCF den Rest des Modells durchdringt. –

+0

Danke für Ihre Antwort. Korrigiere mich, wenn ich deine Antwort falsch lese. Schlägst du vor, dass das Modell/DAO dafür verantwortlich ist, den Mindestwert von "DateTime" im Gegensatz zu Data Access Layer oder SqlServer zu begrenzen? – crush

2

Von MSDN:

Date and time data from January 1, 1753, to December 31, 9999, with an accuracy of one three-hundredth second, or 3.33 milliseconds. Values are rounded to increments of .000, .003, or .007 milliseconds. Stored as two 4-byte integers. The first 4 bytes store the number of days before or after the base date, January 1, 1900. The base date is the system's reference date. Values for datetime earlier than January 1, 1753, are not permitted. The other 4 bytes store the time of day represented as the number of milliseconds after midnight. Seconds have a valid range of 0–59.

SQL verwendet ein anderes System als C# für Datetime-Werte.

Sie können Ihren MinValue als Sentinel-Wert verwenden - und wenn MinValue ist - übergeben Sie Null an Ihr Objekt (und speichern Sie das Datum als Nullwert in der Datenbank).

if(date == dateTime.Minvalue) 
    objinfo.BirthDate = null; 
-5

Verwendung Erweiterungen

public static class DateTimeExtensions 
{ 
    public static DateTime MinValue(this DateTime sqlDateTime) 
    { 
     return new DateTime(1900, 01, 01, 00, 00, 00); 
    } 
} 


DateTime date = DateTime.Now; 
Console.WriteLine("Minvalue is {0} ", date.MinValue().ToShortDateString()); 
2

Einfach gesagt, nicht Verwendung DateTime.MinVaue als Standardwert.

Es gibt ein paar verschiedenen MinValues gibt, je nachdem, welche Umgebung Sie sind in.

Ich hatte einmal ein Projekt, in dem ich ein Windows CE-Projekt wurde die Umsetzung, ich wurde das Framework mit DateTime.MinValue (Jahr 0001) , die Datenbank MinValue (1753) und ein UI-Steuerelement DateTimePicker (ich glaube, es war 1970). Also gab es mindestens 3 verschiedene MinValues ​​, die zu merkwürdigem Verhalten und unerwarteten Ergebnissen führten. (Und ich glaube, es gab sogar eine vierte (!) Version, ich kann mich nicht erinnern, woher es kam.).

Verwenden Sie ein Nullable-Datenbankfeld und ändern Sie stattdessen Ihren Wert in Nullable<DateTime>. Wo kein gültiger Wert in Ihrem Code ist, sollte nicht ein Wert in der Datenbank auch sein. :-)

59

Sehr einfach vermeiden mit DateTime.MinValue verwenden System.Data.SqlTypes.SqlDateTime.MinValue stattdessen.

+4

Verwenden Sie 'System.Data.SqlTypes.SqlDateTime.MinValue.Value 'Wenn Sie den Wert in' DateTime? 'zuweisen wollen, geben Sie das Feld – sohaiby

3

Here is what you can do. Though there are lot many ways to achieve it.

DateTime? d = null;  
if (txtBirthDate.Text == string.Empty) 
    objinfo.BirthDate = d; 
else 
    objinfo.BirthDate = DateTime.Parse(txtBirthDate.Text); 

Note: This will work only if your database datetime column is Allow Null. Else you can define a standard minimum value for DateTime d.

3

ich diese Funktion bin mit

public static bool TryParseSqlDateTime(string someval, DateTimeFormatInfo dateTimeFormats, out DateTime tryDate) 
    { 
     bool valid = false; 
     tryDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; 
     System.Data.SqlTypes.SqlDateTime sdt; 
     if (DateTime.TryParse(someval, dateTimeFormats, DateTimeStyles.None, out tryDate)) 
     { 
      try 
      { 
       sdt = new System.Data.SqlTypes.SqlDateTime(tryDate); 
       valid = true; 
      } 
      catch (System.Data.SqlTypes.SqlTypeException ex) 
      { 

      } 
     } 

     return valid; 
    } 
8

TryParse Obwohl es eine alte Frage ist, ist eine andere Lösung datetime2 für die Datenbankspalte zu verwenden. MSDN Link

+0

richtig ein. SQL Server Datetime ist in der Tat min Start 1753, aber mit SQL Server 2008 und größer sollten Sie Datetime2 verwenden, da dann mit. Net geht zurück zum Jahr 0001 –

+1

Wahrscheinlich die einfachste und wahrscheinlich beste Lösung hier, vorausgesetzt, dass das OP ändern kann der Datenbankabfrageparameter Wie der folgende Link sagt, sollte neue Arbeit "datetime2" verwenden: https://msdn.microsoft.com/en-us/library/ms187819.aspx – Neo

-1

Nun ... seine ganz einfach ein SQL min Datum selbst

DateTime sqlMinDateAsNetDateTime = System.Data.SqlTypes.SqlDateTime.MinValue 
Verwandte Themen