问题
I seem to be getting DbUpdateException
error on db.SaveChanges()
after I edit my Delivery
or Order
. I'm not sure why, it works fine for Create
and Delete
.
Am I missing something somewhere? The GET Edit
methods work fine for both.
I get this exception
error:
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, IDictionary
2 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.WrappedAsyncResultBase
1.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](Func
1 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, Action
1 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, TaskCompletionSource
1 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.InternalDispatcher
1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func3 operation, TInterceptionContext interceptionContext, Action
3 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(Dictionary
2 identifierValues, List`1 generatedValues) at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() InnerException:
Order Controller 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);
}
Delivery Controller 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 });
Order Model:
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; }
Delivery Model:
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; }
}
ViewModels:
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; }
}
PLEASE NOTE: I didn't use ViewModels
for Edit Order
, only for Edit Delivery
.
回答1:
The important part of the error is
Message=The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value`.
Both Delivery
and Order
have a number of DateTime
fields and at least one of them is not being set when you save so their values are 01/01/0001
(i.e. DateTime.MinValue
), but your database table field is DATETIME which only has a year range of 1753-9999
. To prevent the error, you can change the sql type to DATETIME2
which matches the c# DateTime
range.
However, I suspect the real issue is that you really should be setting the DateTime
property. Your Edit()
POST method has
Delivery delivery = new Delivery()
{
DriverID = model.DriverID,
};
db.Deliverys.Add(delivery);
however an Edit()
method suggests your editing and existing object, so it should be
// 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();
来源:https://stackoverflow.com/questions/32412715/dbupdateexception-unhandled-when-trying-to-save-in-post-method-of-delivery-and-o