将datetime2数据类型转换为日期时间数据类型会导致超出范围的值 – 不使用DateTime2

将datetime2数据类型转换为日期时间数据类型会导致超出范围的值。

我的应用程序最近开始显示此错误,这很奇怪,因为它工作得更早。 我没有在“Word”模型中更改与DateTime相关的任何内容。 当我向项目中添加新模型时,它就开始发生了。

我尝试编辑数据时出现服务器错误。 创建和删除工作正常。

控制器:

[HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,UsersLanguage,OtherLanguage,Notes")] Word word, int idOfCollection) { if (ModelState.IsValid) { db.Entry(word).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index", new { idOfCollection = idOfCollection }); } return View(word); } 

模型:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Web; namespace WebLanguageTeacher.Models.MyDatabase { public class Word { public int ID { get; set; } [MinLength(2, ErrorMessage = "Wydaje mi się, że słowo powinno mieć przynajmniej 2 litery ;)")] [DisplayName("Język Użytkownika")] [Required] public string UsersLanguage { get; set; } [MinLength(2, ErrorMessage = "Wydaje mi się, że słowo powinno mieć przynajmniej 2 litery ;)")] [DisplayName("Inny język")] [Required] public string OtherLanguage { get; set; } [DisplayName("Notatki")] public string Notes { get; set; } [DisplayName("Ostatnia powtórka")] public DateTime LastReviewed { get; set; } [DisplayName("Następna powtórka")] public DateTime NextReview { get; set; } [DefaultValue(0)] [DisplayName("Przerwa między powtórkami")] public int ReviewInterval { get; set; } /*W miejsce Difficulty*/ [DisplayName("Nazwa właściciela")] public string OwnerName { get; set; } public virtual Collection Collection { get; set; } [NotMapped] public bool ModifyReview { get; set; } /* Klient przesyła tylko za ile dni będzie następna powtórka, serwer sam generuje datę*/ public Word(){ ModifyReview = false; } } } 

怎么了? 我没有创建任何DateTime2变量,为什么我的应用程序试图将DateTime2转换为DateTime?

我使用ASP.net MVC和EntityFramework。

当未明确设置其值时,DateTime对象默认为DateTime.MinValue。

因此,您的模型中有一个未设置的DateTime对象,并且默认为此,如上所述,它超出了DateTime dbtype的范围,因此EntityFramework将其转换为DateTime2 dbtype,然后导致转换数据库中的错误。

要解决此问题,请检查模型中的所有DateTime对象,并确保将它们设置为DateTime.MinValue以外的任何对象。 如果你不想将值设置为任何东西,那么在db和你的模型中使该字段可以为空,并且事情会起作用

注意,在db列上设置默认值并不能解决这个问题,转换发生得太早,必须明确设置值

  • 日期时间范围:1753年1月1日, – 9999年12月31日

  • DateTime2范围:0001-01-01 – 9999-12-31

使用以下代码以避免冲突。

  protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().Property(o => o.NextReview).HasColumnType("datetime2"); } 

使日期时间可以为空,您需要明确强制它们。 就像属性“LastReviewed”可以为空一样,你应该如下所示声明它。

 [DisplayName("Ostatnia powtórka")] public DateTime? LastReviewed { get; set; } 

与其他日期时间变量相同,如果它们可以为空

如果您不希望更改它们,则需要保留日期时间字段的旧值(以及您不想修改的所有其他字段)。 为此,请从DB中检索旧实体,只需更改编辑表单中更新的字段即可。 例如:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,UsersLanguage,OtherLanguage,Notes")] Word word, int idOfCollection) { if (ModelState.IsValid) { var dbWord = db.Words.Find(word.ID); dbWord.UsersLanguage = word.UsersLanguage; dbWord.OtherLanguage = word.OtherLanguage; dbWord.Notes = word.Notes; db.SaveChanges(); // in this case dbWord is saved so datetime fields remains intact return RedirectToAction("Index", new { idOfCollection = idOfCollection }); } return View(word); } 

通过在DateTime之后添加问号使您的属性可以为空。

  public DateTime? SentOn { get; set; }