DbContext और SetInitializer का उपयोग करके डेटाटाइम 2 की आउट-ऑफ-द-रेंज रूपांतरण त्रुटि कैसे ठीक करें?


136

मैं Entity फ्रेमवर्क 4.1 के साथ शुरू किए गए DbContext और Code First API का उपयोग कर रहा हूं।

डाटा मॉडल जैसे बुनियादी डेटा प्रकार का उपयोग करता है stringऔर DateTime। केवल डेटा एनोटेशन मैं कुछ मामलों में उपयोग कर रहा हूं [Required], लेकिन यह किसी भी DateTimeगुण पर नहीं है । उदाहरण:

public virtual DateTime Start { get; set; }

DbContext उपवर्ग भी सरल और ऐसा दिखता है:

public class EventsContext : DbContext
{
    public DbSet<Event> Events { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Event>().ToTable("Events");
    }
}

प्रारंभकर्ता या तो इस साल या अगले साल में समझदार मूल्यों के मॉडल में सेट दिनांकों।

हालाँकि जब मैं इनिशलाइज़र चलाता हूँ, मुझे यह त्रुटि मिलती है context.SaveChanges():

डेटाटाइम के डेटा प्रकार में डेटाइम 2 प्रकार के रूपांतरण के परिणामस्वरूप आउट-ऑफ-द-रेंज मान होता है। बयान समाप्त कर दिया गया है।

मुझे समझ नहीं आता कि ऐसा क्यों हो रहा है क्योंकि सब कुछ इतना सरल है। मुझे यह भी पता नहीं है कि इसे कैसे ठीक किया जाए क्योंकि संपादित करने के लिए कोई edmx फ़ाइल नहीं है।

कोई विचार?


2
क्या आप एसक्यूएल प्रोइलर का उपयोग एसक्यूएल स्टेटमेंट डालने / अपडेट करने के लिए कर सकते हैं? यह कहना काफी कठिन है कि यहां क्या हो रहा है - हम आपके इनिशियलाइज़र या संस्थाओं को नहीं देखते हैं। SQL Profiler आपको समस्या का स्थानीयकरण करने में बहुत मदद करेगा।
लादिस्लाव मृका

1
मेरे मामले में मैंने एक फ़ील्ड को टेबल और एडिट फॉर्म में जोड़ा था, बिंद को अपडेट करना भूल गया था और मेरा फील्ड NULL में सेट हो रहा था। तो त्रुटि ने मेरे निरीक्षण को सही करने में मदद की।
स्ट्रेटनॉन

जवाबों:


186

आपको यह सुनिश्चित करना होगा कि प्रारंभ SqlDateTime.MinValue (1 जनवरी, 1753) से अधिक या उसके बराबर है - डिफ़ॉल्ट रूप से प्रारंभ DateTime.MinValue (1 जनवरी, 0001) के बराबर है।


14
मैंने अपनी कुछ आरंभिक वस्तुओं को एक निर्धारित तिथि के बिना छोड़ दिया था, इसलिए यह DateTime.MinValue के लिए डिफ़ॉल्ट हो जाता।
एलेक्स एंगस

मैंने वो भी किया। Asp.net पहचान ApplicationUser ऑब्जेक्ट के लिए एक कस्टम दिनांक फ़ील्ड जोड़ा गया, फिर इसे किसी ऐसी चीज़ के लिए प्रारंभ करना भूल गया। :
19

मेरे मामले में, समस्या मिनट की तारीख में थी, 01/01/0001 त्रुटि उत्पन्न कर रहा था।
मचाडो

मैं dateTime.minvalue की जांच कैसे कर सकता हूं?
अनबील

1
थोड़ी देर, लेकिन @Anabeil आपको VS / linqpad की तत्काल विंडो में सिर्फ Console.WriteLine (DateTime.MinValue) करने में सक्षम होना चाहिए
डेटाइम.इन.विनवैल्यू

22

सरल। अपने कोड पर सबसे पहले, DateTime का दिनांक DateTime पर सेट करें। तो आप डेटाबेस में nullable DateTime प्रकार के साथ काम कर सकते हैं। इकाई उदाहरण:

public class Alarme
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        public DateTime? DataDisparado { get; set; }//.This allow you to work with nullable datetime in database.
        public DateTime? DataResolvido { get; set; }//.This allow you to work with nullable datetime in database.
        public long Latencia { get; set; }

        public bool Resolvido { get; set; }

        public int SensorId { get; set; }
        [ForeignKey("SensorId")]
        public virtual Sensor Sensor { get; set; }
    }

6
हमेशा ऐसा नहीं होता। {1/1/0001 12:00:00 AM} यह त्रुटि भी सामने आती है
eran otzap

20

कुछ मामलों में, DateTime.MinValue (या समतुल्य,default(DateTime) ) का उपयोग अज्ञात मूल्य को इंगित करने के लिए किया जाता है।

यह सरल विस्तार विधि ऐसी स्थितियों को संभालने में मदद कर सकती है:

public static class DbDateHelper
{
    /// <summary>
    /// Replaces any date before 01.01.1753 with a Nullable of 
    /// DateTime with a value of null.
    /// </summary>
    /// <param name="date">Date to check</param>
    /// <returns>Input date if valid in the DB, or Null if date is 
    /// too early to be DB compatible.</returns>
    public static DateTime? ToNullIfTooEarlyForDb(this DateTime date)
    {
        return (date >= (DateTime) SqlDateTime.MinValue) ? date : (DateTime?)null;
    }
}

उपयोग:

 DateTime? dateToPassOnToDb = tooEarlyDate.ToNullIfTooEarlyForDb();

13

आप क्षेत्र को अशक्त बना सकते हैं, यदि वह आपके विशिष्ट मॉडलिंग चिंताओं के अनुकूल हो। एक अशक्त दिनांक को उस दिनांक के लिए ज़ब्त नहीं किया जाएगा जो SQL दिनांक समय सीमा के भीतर नहीं है जिस तरह से डिफ़ॉल्ट मान होगा। एक अन्य विकल्प स्पष्ट रूप से एक अलग प्रकार का नक्शा है, शायद,

.HasColumnType("datetime2")

12

भले ही यह सवाल काफी पुराना है और पहले से ही महान जवाब हैं, मैंने सोचा कि मुझे एक और डाल देना चाहिए जो इस समस्या को हल करने के लिए 3 अलग-अलग तरीकों को बताता है।

1 दृष्टिकोण

स्पष्ट रूप से नक्शा DateTimeसंपत्ति public virtual DateTime Start { get; set; }के लिए datetime2तालिका में कॉलम इसी में। क्योंकि डिफ़ॉल्ट रूप से EF इसे मैप करेगा datetime

यह धाराप्रवाह एपीआई या डेटा एनोटेशन द्वारा किया जा सकता है।

  1. धाराप्रवाह एपीआई

    DbContext वर्ग में संपत्तियों के ऊपर OnModelCreatingऔर कॉन्फ़िगर करें Start(स्पष्टीकरण कारणों से यह EntityClass वर्ग की संपत्ति है)।

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Configure only one property 
        modelBuilder.Entity<EntityClass>()
            .Property(e => e.Start)
            .HasColumnType("datetime2");
    
       //or configure all DateTime Preperties globally(EF 6 and Above)
        modelBuilder.Properties<DateTime>()
            .Configure(c => c.HasColumnType("datetime2"));
    }
  2. डेटा एनोटेशन

    [Column(TypeName="datetime2")]
    public virtual DateTime Start { get; set; }

दूसरा दृष्टिकोण

StartEntityClass कंस्ट्रक्टर में एक डिफ़ॉल्ट मान के लिए प्रारंभ करें। यह अच्छा है जैसे कि किसी कारण Startसे इकाई को डेटाबेस प्रारंभ में सहेजने से पहले मान सेट नहीं होता है, हमेशा एक डिफ़ॉल्ट मान होगा। सुनिश्चित करें कि डिफ़ॉल्ट मान SqlDateTime.MinValue से अधिक या बराबर है (1 जनवरी, 1753 से 31 दिसंबर, 9999 तक)

public class EntityClass
{
    public EntityClass()
    {
        Start= DateTime.Now;
    }
    public DateTime Start{ get; set; }
}

तीसरा दृष्टिकोण

के बाद Startप्रकार DateTime अशक्त होने के लिए बनाओ -?DateTime

public virtual DateTime? Start { get; set; }

अधिक स्पष्टीकरण के लिए इस पोस्ट को पढ़ें


8

यदि आपके DateTimeगुण डेटाबेस में अशक्त हैं, तो DateTime?संबंधित ऑब्जेक्ट संपत्तियों के लिए उपयोग करना सुनिश्चित करें या EF DateTime.MinValueअनसाइन किए गए मानों के लिए पास होगा जो कि SQL डेटाइम प्रकार को संभाल सकते हैं की सीमा के बाहर है।


8

मेरा समाधान सभी डेटाटाइम कॉलम को डेटाइम 2 पर स्विच करना था, और किसी भी नए कॉलम के लिए डेटटाइम 2 का उपयोग करना था। दूसरे शब्दों में, EF डिफ़ॉल्ट रूप से datetime2 का उपयोग करें। इसे अपने संदर्भ में OnModelCreating विधि में जोड़ें:

modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));

कि सभी DateTime और DateTime मिलेंगे? आपके सभी संस्थाओं पर गुण।


3

कंस्ट्रक्टर में स्टार्ट प्रॉपर्टी को इनिशियलाइज़ करें

Start = DateTime.Now;

मेरे लिए यह तब काम आया जब मैं कोड फर्स्ट में ASP .Net आइडेंटिटी फ्रेमवर्क के यूज़र्स टेबल (AspNetUser) में कुछ नए फ़ील्ड जोड़ने की कोशिश कर रहा था। मैंने IdentityModels.cs में Class - ApplicationUser को अपडेट किया और मैंने DateTime का एक फ़ील्ड लास्टलाइन जोड़ा।

public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
            CreatedOn = DateTime.Now;
            LastPassUpdate = DateTime.Now;
            LastLogin = DateTime.Now;
        }
        public String FirstName { get; set; }
        public String MiddleName { get; set; }
        public String LastName { get; set; }
        public String EmailId { get; set; }
        public String ContactNo { get; set; }
        public String HintQuestion { get; set; }
        public String HintAnswer { get; set; }
        public Boolean IsUserActive { get; set; }

        //Auditing Fields
        public DateTime CreatedOn { get; set; }
        public DateTime LastPassUpdate { get; set; }
        public DateTime LastLogin { get; set; }
    }

2

उपयोगकर्ता @ andygjp के उत्तर के आधार पर, यह बेहतर है यदि आप आधार Db.SaveChanges()विधि को ओवरराइड करते हैं और किसी भी तारीख को ओवरराइड करने के लिए एक फ़ंक्शन जोड़ते हैं जो SqlDateTime.MinValue और SqlDateTime.MaxVueue के बीच नहीं आती है।

यहाँ नमूना कोड है

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

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries().Where(x => (x.State == EntityState.Added || x.State == EntityState.Modified)))
        {
            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;
                    }
                }
            }
        }
    }
}

Https://stackoverflow.com/a/11297294/9158120 पर उपयोगकर्ता @ आकाश-देव की टिप्पणी से लिया गया


1

मेरे पास एक ही मुद्दा था और मेरे मामले में मैं DateTime.Now के बजाय नए DateTime () को तारीख सेट कर रहा था


0

मेरे मामले में यह तब हुआ जब मैंने इकाई का उपयोग किया और sql तालिका में डेटटाइम == getdate () का डिफ़ॉल्ट मान है। इसलिए मैंने इस क्षेत्र के लिए एक मूल्य निर्धारित किया।


0

मैं पहले डेटाबेस का उपयोग कर रहा हूं और जब यह त्रुटि मुझसे हुई तो मेरा समाधान edmx फ़ाइल में प्रोवाइडरमैनफेस्टटोकन = "2005" को बाध्य करना था (मॉडल को SQL सर्वर 2005 के साथ संगत बनाना)। पता नहीं अगर कोड पहले के लिए कुछ इसी तरह संभव है।


0

एक पंक्ति इसे ठीक करती है:

modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));

इसलिए, मेरे कोड में, मैंने जोड़ा:

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

DBContext उपवर्ग में उस एक पंक्ति को जोड़ने से शून्य OnModelCreating अनुभाग को काम करना चाहिए।


0

मेरे मामले में, EF6 में कुछ रिफैक्टरिंग के बाद, मेरे परीक्षण मूल पोस्टर के समान त्रुटि संदेश के साथ विफल हो रहे थे, लेकिन मेरे समाधान का डेटटाइम फ़ील्ड्स के साथ कोई लेना-देना नहीं था।

इकाई बनाते समय मुझे एक आवश्यक फ़ील्ड याद आ रही थी। एक बार मैंने लापता फ़ील्ड को जोड़ दिया, तो त्रुटि दूर हो गई। मेरी इकाई में दो DateTime हैं? फ़ील्ड लेकिन वे समस्या नहीं थे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.