Datetime2 veri türünün datetime veri türüne dönüştürülmesi, aralık dışı bir değerle sonuçlandı


174

Benim HomeController aşağıdaki kodu var:

public ActionResult Edit(int id)
{
    var ArticleToEdit = (from m in _db.ArticleSet where m.storyId == id select m).First();
    return View(ArticleToEdit);
}

[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Article ArticleToEdit)
{
    var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();
    if (!ModelState.IsValid)
        return View(originalArticle);

    _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit);
    _db.SaveChanges();
    return RedirectToAction("Index");
}

Ve bu Düzenle yönteminin görünümüdür:

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

Gönder düğmesine bastığımda hatayı alıyorum: {"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated."}Sorunun ne olduğuna dair bir fikrin var mı? Düzenleme yönteminin DB yayınlanan değeri düzenlenmiş için güncellemeye çalıştığını varsayıyorum ama bir nedenden dolayı hoşuna gitmiyor ... Tarih neden belirtildiği gibi neden dahil olduğunu görmüyorum rağmen düzenleme için denetleyici yöntemi?


1
modelBuilder.Entity<WorldInfo>().Property(d => d.CurrentTime).HasColumnType("datetime2");
Anthony Nichols

Yanıtlar:


166

Sorun, ApplyPropertyChangesyalnızca formdaki verilerle (başlık, hikaye ve resim) doldurulmuş bir model nesnesiyle kullanmanızdır . SQL Server aralığının dışında 0001-01-01 olarak ayarlanmış ApplyPropertyChanges, başlatılmamış olanlar da dahil olmak üzere nesnenin tüm özelliklerinde değişiklikler uygular .DateTimeDATETIME

Kullanmak yerine ApplyPropertyChanges, değiştirilen nesneyi almanızı, formunuzun düzenlediği belirli alanları değiştirmenizi ve ardından nesneyi bu değişikliklerle kaydetmenizi öneririm; bu şekilde, yalnızca değiştirilen alanlar değiştirilir. Alternatif olarak, diğer alanları doldurulmuş olarak sayfanıza gizli girişler yerleştirebilirsiniz, ancak eşzamanlı düzenlemelerle pek de kolay olmaz.

Güncelleme:

Aşağıda, nesnenizin bazı alanlarını güncellemeye yönelik denenmemiş bir örnek verilmiştir (bu, LINQ to SQL kullandığınızı varsayar):

var story = _db.ArticleSet.First(a => a.storyId == ArticleToEdit.storyId);
story.headline = ArticleToEdit.headline;
story.story = ArticleToEdit.story;
story.image = ArticleToEdit.image;
story.modifiedDate = DateTime.Now;
_db.SubmitChanges();

Çok yararlı :) Ben bunu belirtmemişti neden tarih değiştirildi merak ediyordum. Daha sonra ApplyPropertyChanges kullanmayacak şekilde Edit yöntemini değiştirmenize yardımcı olabilir misiniz? ASP.NET'te yeniyim ve şu anda hepsini tam olarak anlamıyorum. Teşekkürler dostum.
Cameron

Tarihi geçerli tarihe ayarlamak istersem ne yani. makalenin güncellendiği tarih? Muhtemelen bu en iyi seçenek olacak ve oyunda uyguladığım ApplyPropertyChanges ile çalışacağını varsayıyorum.
Cameron

Düzenlememi görün ( modifiedDatemülkünüzün adı olduğunu varsayar )
Jacob

SubmitChanges Uygulamamda çalışmıyor: / story.modifiedDate = DateTime.Now;Mevcut koduma bit eklemek mümkün mü? Teşekkürler
Cameron

1
genel DateTime yerine public DateTime CreatedDate ayarladığımızda bu hata oluşur? CreatedTate, çünkü DateTime boş olamaz, bu yüzden neden aralık dışı hatası veriyor. yardımcı olabilir, ancak sorunumu çözdü.
adnan

115

Bu, Entity Framework kullanırken insanların karşılaştığı yaygın bir hatadır. Bu, kaydedilen tabloyla ilişkilendirilen varlık zorunlu bir tarih / saat alanına sahip olduğunda ve bunu bir değerle ayarlamazsanız oluşur.

Varsayılan datetime nesnesi değeri ile oluşturulur 01/01/1000ve null yerine kullanılır. Bu, tarih değerlerini en başından 1753-01-01 00:00:00itibaren tutabilecek ancak daha önce değil, aralık dışı özel duruma yol açabilecek tarih / saat sütununa gönderilir .

Bu hata, veritabanı alanını null değerini kabul edecek şekilde değiştirerek veya alanı bir değerle başlatarak çözülebilir.


3
Bu, veritabanındaki datetime alanı isteğe bağlı olduğunda ve değer ayarlanmadığında gerçekleşir. Bu yaygın insan hatası değildir, bu EF mimari sorunlarından biridir.
GSoft Consulting

1
EF'nin DB'deki türü görmesi ve buna göre ayarlaması veya en azından daha kesin bir hata atması veya atması gerektiğine katılıyorum. Yukarı tarafta, her zamanki yerine 2 seçenek sağladığınızdan cevabınızı beğeniyorum - dosyalanmış min değeri ile başlatın.
DanteTheSmith

43

DATETIME1753/1/1 ila "sonsuzluk" u (9999/12/31) DATETIME2desteklerken, 0001/1/1'i sonsuzluk boyunca destekler.

msdn

Cevap: Sanırım DateTime'0001/1/1' değeriyle tasarruf etmeye çalışıyorsunuz . Sadece kesme noktasını ayarlayın ve hata ayıklayın, eğer öyleyse değiştirinDateTimenull normal tarih ile veya ayarlayın.


Denetleyiciye ne koyarım? Hata ayıklama, yukarıda gönderdiğim hatayı getiriyor. Teşekkürler.
Cameron

burada hata görünüyor -> _db.SaveChanges (); Kesme çizgisini bu çizgiden önce ayarlayabilirsiniz ...
Andrew Orsich

Evet yaptı. Sonra InnerException bakmak onların SaveChanges bir hata olduğunu söylüyor ve bu yüzden hata bu yüzden gönderilen hata nedeniyle diyor!
Cameron

DateTime değerini _db.SaveChanges () 'den önce kontrol ettiniz mi? aradı? '1753/1/1' den daha iyi olmalı.
Andrew Orsich

OriginalArticle tarih değeri {18/10/2009 00:00:00} ve ArticleToEdit tarih değeri {01/01/0001 00:00:00} olduğundan, tarihi, İstemiyorum ama biçim aynı olduğu için neden hata verdiğini açıklamıyor mu?
Cameron

14

Bu beni delirtiyordu. Geçersiz bir tarih ( DateTime?) kullanmaktan kaçınmak istedim . Ben de ( modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");) SQL 2008'in datetime2 türünü kullanma seçeneği yoktu .

Sonunda aşağıdakileri seçtim:

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

10

Bu sorunu modele ekleyerek de düzeltebilirsiniz (Entity Framework sürümü> = 5)

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreationDate { get; set; }

8

Tarihsaat ve null değerine izin veren bir sütun varsa, bu hatayı alırsınız. Önce nesneye geçmek için bir değer ayarlamanızı öneririz. .SaveChanges ();


5

Aşağıdaki gibi benim model (ilk kod) değiştirdikten sonra bu hatayı aldım:

public DateTime? DateCreated

için

public DateTime DateCreated

DateCreated öğesinde null değerli mevcut satırlar bu hataya neden oldu. Bu nedenle , alanı standart bir değerle başlatmak için SQL UPDATE deyimini el ile kullanmak zorunda kaldım .

Başka bir çözüm, dosyalanmış için varsayılan değerin belirtilmesi olabilir.


3

Benim durumumda, veritabanının tablosunda kullandığım sınıftan başlatıcıda, DateTime özelliğim için herhangi bir varsayılan değer ayarlamıyordum, bu nedenle @Andrew Orsich'in cevabında açıklanan soruna neden oldum. Bu yüzden sadece özelliği nullable yaptı. Ya da yapıcıya DateTime.Now vermiş olabilir. Umarım birine yardımcı olur.


3

Varlık çerçevesi kullandığınız anlaşılıyor. Benim çözümüm, tüm datetime sütunlarını datetime2 olarak değiştirmek ve yeni sütunlar için datetime2 kullanmak, diğer bir deyişle EF varsayılan olarak datetime2 kullanmak yapmak oldu. Bağlamınızdaki OnModelCreating yöntemine ekleyin:

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

Bu tüm DateTime ve DateTime alacak? modelinizdeki tüm varlıkların özelliklerini gösterir.


2

Ben aynı sorun vardı, ne yazık ki, benim modelde iki DateTime özelliği var ve SaveChanges yapmadan önce bir DateTime özelliği null.

Bu nedenle, değişiklikleri kaydetmeden önce modelinizin DateTime değerine sahip olduğundan emin olun veya hatayı önlemek için sıfırlanabilir yapın:

public DateTime DateAdded { get; set; }   //This DateTime always has a value before persisting to the database.
public DateTime ReleaseDate { get; set; }  //I forgot that this property doesn't have to have DateTime, so it will trigger an error

Bu benim sorunumu çözüyor, veritabanına devam etmeden önce model tarihinizin doğru olduğundan emin olmak meselesi:

public DateTime DateAdded { get; set; }
public DateTime? ReleaseDate { get; set; }

2

Entity Framework sürüm> = 5 kullanıyorsanız, sınıfınızın DateTime özelliklerine [DatabaseGenerated (DatabaseGeneratedOption.Computed)] ek açıklamasını uygulamak, veritabanı tablosunun tetikleyicisinin kayıt oluşturma ve kayıt güncellemesi için tarih girme işini neden olmadan yapmasına izin verir için Entity Framework kodunuzu girin.

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateCreated { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateUpdated { get; set; }

Bu, Dongolo Jeno tarafından yazılan ve Gille Q tarafından düzenlenen 6. cevaba benzer.


1

Ayrıca, hatanın oluştuğu kodun bir kısmını bilmiyorsanız, mssql ile entegre sql profiler kullanarak "kötü" sql yürütme profili olabilir.

Kötü datetime parametresi şöyle bir şey görüntüler:

kötü param


1

Bu sorun genellikle bir varlığı güncellemeye çalıştığınızda oluşur. Örneğin DateCreated, [Zorunlu] adında bir alan içeren bir varlığınız var ve kayıt eklediğinizde hata döndürülmüyor ancak belirli bir varlığı güncellemek istediğinizde,

datetime2 dönüşümü aralık dışı hatası.

İşte çözüm:

Düzenleme görünümünüzde, yani edit.cshtmlMVC kullanıcıları için tek yapmanız gereken DateCreateddüzenleme verisinin birincil anahtarı için gizli alanın hemen altına gizli bir form alanı eklemektir .

Misal:

@Html.HiddenFor(model => model.DateCreated)

Bunu düzenleme görünümünüze eklediğinizde, sizi garanti ettiğim hiçbir hatayı almayacaksınız.


1

Tarih değişkeniniz için null değeri etkinleştirmeniz gerekir:

 public Nullable<DateTime> MyDate{ get; set; }

0

Mülkünüzü sıfırlanabilir yapmayı deneyin.

    public DateTime? Time{ get; set; }

Benim için çalıştı.


0

DB'ye erişiminiz varsa, DB sütun türünü datetime yerine datetime2 (7) olarak değiştirebilirsiniz, yine de bir datetime nesnesi gönderir ve kaydedilir


0

Model nullable datetime değerine sahip olmalıdır. Değiştirilmesi gereken nesneyi almak için daha önce önerilen yöntem ApplyPropertyChanges yerine kullanılmalıdır. Benim durumumda Nesnemi kaydetmek için bu yöntemi vardı:

public ActionResult Save(QCFeedbackViewModel item)

Ve sonra hizmette, kullanarak almak:

RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null 

Hizmet kodunun tamamı aşağıdaki gibidir:

 var add = new QC_LOG_FEEDBACK()
            {

                QCLOG_ID = item.QCLOG_ID,
                PRE_QC_FEEDBACK = item.PRE_QC_FEEDBACK,
                RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null,
                PRE_QC_RETURN = item.PRE_QC_RETURN.HasValue ? Convert.ToDateTime(item.PRE_QC_RETURN) : (DateTime?)null,
                FEEDBACK_APPROVED = item.FEEDBACK_APPROVED,
                QC_COMMENTS = item.QC_COMMENTS,
                FEEDBACK = item.FEEDBACK
            };

            _context.QC_LOG_FEEDBACK.Add(add);
            _context.SaveChanges();

0

[Çözüldü] In Varlık Framework Kod İlk (benim durumumda) sadece değişen DateTimeetmek DateTime?benim sorunu çözmek.

/*from*/ public DateTime SubmitDate { get; set; }
/*to  */ public DateTime? SubmitDate { get; set; }

0

Hata: datetime2 veri türünün datetime veri türüne dönüştürülmesi, aralık dışı bir değerle sonuçlandı.

Nedeniyle bu hata oluştu DEĞİL EF kullanarak SQL veritabanında NOT NULL tarih sütununda karşı herhangi bir değeri atayarak ve aynı atayarak çözüldü.

Bu yardımcı olur umarım!


0

Sınıflarımı Veritabanı İlkesi yaklaşımından oluştururken bu sorunla karşılaştım. Sadece Convert.DateTime (dateCausingProblem) kullanarak çözüldü Aslında, her zaman geçmeden önce değerleri dönüştürmeye çalışın, Beklenmedik değerlerden sizi kurtarır.


0

tarih alanınızın giriş biçimini yyyy / aa / gg olan gerekli varlık biçimiyle eşleştirmeniz gerekir


1
OP'nin sorusunu sağlayan başka cevaplar da var ve bunlar bir süre önce yayınlandı. Bir cevap gönderirken bkz: İyi bir cevabı nasıl yazarım? , özellikle eski soruları yanıtlarken yeni bir çözüm veya çok daha iyi bir açıklama eklediğinizden emin olun.
help-info.de
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.