分别编辑后尝试保存在交付和订单的 POST 方法中时未处理 DbUpdateException

DbUpdateException unhandled when trying to save in POST method of Delivery and Order after editing respectively

在我编辑 DeliveryOrder 后,我似乎在 db.SaveChanges() 上收到 DbUpdateException 错误。我不确定为什么,它适用于 CreateDelete

我是不是漏了什么地方? GET Edit 方法对两者都适用。

我得到这个 exception 错误:

System.Data.Entity.Infrastructure.DbUpdateException was unhandled by user code HResult=-2146233087 Message=An error occurred while updating the entries. See the inner exception for details.
Source=EntityFramework StackTrace: at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at HealthHabitat.Controllers.DeliveryController.Edit(DeliveryVM model) in c:\Users\Luffy\Desktop\HealthHabitat V25\HealthHabitat\Controllers\DeliveryController.cs:line 172 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() at System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f() InnerException: System.Data.Entity.Core.UpdateException HResult=-2146233087 Message=An error occurred while updating the entries. See the inner exception for details. Source=EntityFramework StackTrace: at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.b__2(UpdateTranslator ut) at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func2 updateFunction) at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.b__27() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func1 operation) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction) at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() InnerException: System.Data.SqlClient.SqlException HResult=-2146232060 Message=The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated. Source=.Net SqlClient Data Provider ErrorCode=-2146232060 Class=16 LineNumber=1 Number=242 Procedure="" Server=(LocalDb)\v11.0 State=3 StackTrace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b__c(DbCommand t, DbCommandInterceptionContext1 c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func3 operation, TInterceptionContext interceptionContext, Action3 executing, Action3 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary2 identifierValues, List`1 generatedValues) at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() InnerException:

订单控制器POST:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "OrderID,HospitalID,StaffID,Date,Time,Expected_Date")] Order order)
{
    if (ModelState.IsValid)
    {
        db.Entry(order).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Details", new { id = order.OrderID });
    }
    //ViewBag.DeliveryID = new SelectList(db.Deliverys, "DeliveryID", "DeliveryID", order.DeliveryID);
    ViewBag.HospitalID = new SelectList(db.Hospitals, "HospitalID", "Name", order.HospitalID);
    ViewBag.StaffID = new SelectList(db.Staffs, "StaffID", "First_Name", order.StaffID);
    return View(order);
}

交付控制器POST:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(DeliveryVM model)
{
    Delivery delivery = new Delivery()
    {
        DriverID = model.DriverID,

    };
    db.Deliverys.Add(delivery);
    db.SaveChanges();
    // save the selected orders based on the ID of the Delivery object
    IEnumerable<int> selectedOrders = model.Orders.Where(o => o.IsSelected).Select(o => o.ID);
    foreach (int ID in selectedOrders)
    {
        Order order = db.Orders.Where(o => o.OrderID == ID).FirstOrDefault();
        order.DeliveryID = delivery.DeliveryID;
        db.Entry(order).State = EntityState.Modified;
    }

    db.SaveChanges();
    return RedirectToAction("Details", new { id = delivery.DeliveryID });

订购型号:

public int OrderID { get; set; }

    [Display(Name = "Hospital")]
    public int HospitalID { get; set; }

    [Display(Name = "Staff")]
    public int StaffID { get; set; }
    public int? DeliveryID { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime Date { get; set; }

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime Time { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime Expected_Date { get; set; }
    public virtual Hospital Hospital { get; set; }
    public virtual Staff Staff { get; set; }
    public virtual Delivery Delivery { get; set; }
    public virtual ICollection<OrderItem> OrderItems { get; set; }

交付模式:

public enum Status
{
   Dispatched, Delayed, Delivered
}
public class Delivery
{

    public int DeliveryID { get; set; }
    [Display(Name = "Driver")]
    public int DriverID { get; set; }
    public Status Status { get; set; }

    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string Comment { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date Dispatched")]
    public DateTime Dispatched_Date { get; set; }

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
    [Display(Name = "Time Dispatched")]
    public DateTime Dispatched_Time { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date Delivered")]
    public DateTime? Delivered_Date { get; set; }

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
    [Display(Name = "Time Delivered")]
    public DateTime? Delivered_Time { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date Delayed")]
    public DateTime? Delayed_Date { get; set; }

    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
    [Display(Name = "Time Delayed")]
    public DateTime? Delayed_Time { get; set; }



    public virtual Driver Driver { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

视图模型:

    public enum Status
    {
        Dispatched, Delayed, Delivered
    }
    public class DeliveryVM
    {
        public int? ID { get; set; }
        public int DriverID { get; set; }

        public Status Status { get; set; }

        [DisplayFormat(ConvertEmptyStringToNull = false)]
        public string Comment { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date Dispatched")]
        public DateTime Dispatched_Date { get; set; }

        [DataType(DataType.Time)]
        [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
        [Display(Name = "Time Dispatched")]
        public DateTime Dispatched_Time { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date Delivered")]
        public DateTime? Delivered_Date { get; set; }

        [DataType(DataType.Time)]
        [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
        [Display(Name = "Time Delivered")]
        public DateTime? Delivered_Time { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date Delayed")]
        public DateTime? Delayed_Date { get; set; }

        [DataType(DataType.Time)]
        [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
        [Display(Name = "Time Delayed")]
        public DateTime? Delayed_Time { get; set; }
        public SelectList DriverList { get; set; }
        public List<OrderVM> Orders { get; set; }
    }

public class OrderVM
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address_1 { get; set; }
    public string Address_2 { get; set; }
    public string Address_3 { get; set; }
    public string Province { get; set; }
    public DateTime Date { get; set; }
    public int DeliveryID { get; set; }
    public bool IsSelected { get; set; }


}

请注意: 我没有将 ViewModels 用于 Edit Order,仅用于 Edit Delivery

错误的重要部分是

Message=The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value`.

DeliveryOrder 都有多个 DateTime 字段,并且至少有一个字段在您保存时未设置,因此它们的值为 01/01/0001(即 DateTime.MinValue),但您的数据库 table 字段是 DATETIME,它的年份范围仅为 1753-9999。为防止错误,您可以将 sql 类型更改为与 c# DateTime 范围匹配的 DATETIME2

但是,我怀疑真正的问题是您真的应该设置 DateTime 属性。您的 Edit() POST 方法有

Delivery delivery = new Delivery()
{
    DriverID = model.DriverID,
};
db.Deliverys.Add(delivery);

然而 Edit() 方法建议您编辑现有对象,因此它应该是

// Get the data model based on the ID of the view model
Delivery delivery = db.Delivery.Find(model.ID);
// Map the view model properties to the data model
delivery.DriverID = model.DriverID;
// Mark as modified and save
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();