0

I'm trying to delete a record in the database by simply using db.'table'.remove('object') but when calling db.SaveChanges() exception is thrown.

'An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code'

My deleting method in controller

public ActionResult Delete(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Customer customer = db.Customers.Find(id);
    if (customer == null)
    {
        return HttpNotFound();
    }
    db.Customers.Remove(customer);
    db.SaveChanges();

    return RedirectToAction("Index");
}

Model:

public class Customer
{
    [Key, ForeignKey("User")]
    public int UserId { get; set; }
    public string Email { get; set; }
    public virtual CreditCard CreditCard { get; set; }
    public virtual ShoppingCart ShoppingCart { get; set; }
    public virtual List<Enquiry> Enquiries { get; set; }
    public virtual List<Order> Orders { get; set; }
    public virtual User User { get; set; }
}
public class User
{
    [Key]
    public int Id { set; get; }
    public string Username { set; get; }
    public string Password { set; get; }
    public string FirstName { set; get; }
    public string Surname { set; get; }
    public virtual UserRole UserRole { get; set; }
}

public class ShoppingCart
    {
        [Key, ForeignKey("Customer")]
        public int Id { get; set; }
        public virtual List<CartItem> CartItems { get; set; }
        public virtual Customer Customer { get; set; }
    }

Part of the exception:

A DbUpdateException was caught while saving changes. Type: Customer_8D9A6B7F7D247C9CB9F95E830039791E299E94FC91841FD33610DD1804AEF739 was part of the problem. 

Full exception:

System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.ShoppingCarts_dbo.Customers_Id". The conflict occurred in database "MVC_COMP1562.Models.SchemaDBContext", table "dbo.ShoppingCarts", column 'Id'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 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.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
   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()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 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.<SaveChangesInternal>b__27()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 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()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at MVC_COMP1562.Controllers.CustomersController.Delete(Nullable`1 id) in C:\Users\kacpe\Documents\Visual Studio 2015\Projects\MVC_COMP1562\MVC_COMP1562\Controllers\CustomersController.cs:line 165
Higeath
  • 99
  • 1
  • 9
  • Maybe you can use a try/catch in orther to get some more details of the exception and post them here and we can help you. – mako Apr 02 '17 at 00:36
  • @mako I found a few things I could output from the exception, I added it to the question, what else/how can I output more detailed info? – Higeath Apr 02 '17 at 00:42
  • Maybie it's a relation problem? Have you try delete instead of remove?http://stackoverflow.com/questions/17723626/entity-framework-remove-vs-deleteobject – Arkadiusz Raszeja Apr 02 '17 at 00:55
  • @ArkadiuszRaszeja I believe deleteObject was deprecated in older version of EF – Higeath Apr 02 '17 at 01:01
  • Please post other exception details like StackTrace and the Message if that wasn't what you posted. – mako Apr 02 '17 at 01:06
  • @mako http://imgur.com/a/KyfOr I'm not sure what else can I attach – Higeath Apr 02 '17 at 01:10
  • There is an inner exception, you should catch the exception. Please write `try` in the line before the `Remove`, then open bracket after try, then close the bracket after `SaveChanges` then add a catch block after that to capture the exception and use a breakpoint to check the inner exception. – mako Apr 02 '17 at 01:14
  • Something like this: http://imgur.com/a/qYrCY, and then put the breackpoint in the bracket after the catch line, and show here the inner exception type and message. e.InnerException, e.InnerException.Message, e.InnerException.GetType() – mako Apr 02 '17 at 01:19
  • @mako added to the question – Higeath Apr 02 '17 at 01:21
  • OK then, it's like I said in the answer, first you must delete the related row in table `dbo.ShoppingCarts`. Please try that. – mako Apr 02 '17 at 01:45

1 Answers1

0

It seems you have another Table called dbo.ShoppingCarts about a Shopping Cart, which have one or more rows related to the Customer you are trying to delete.
So first you must delete the rows related to that customer an then you can delete the customer. That happens because the Customer id is foreign key in that other table.
If that is no exactly the case, please add your ShoppingCarts class to the question.

mako
  • 78
  • 1
  • 6
  • Added shoppingcart to the question, even when I delete shopping cart first it still throws an exception when deleting customer. – Higeath Apr 02 '17 at 01:42
  • Maybe there is another relation with Customer and another table. Can you port your tables diagram, where all foreign keys can be seen? – mako Apr 02 '17 at 01:50
  • I see now that you may have relations to other Tables as well, such as `Inquiry` and `Order`, if there are `Foreign Keys` pointing to `Customer`, then it's the same, you have to delete every row in other tables that is pointing to the customer you are trying to delete. – mako Apr 02 '17 at 02:01
  • Check this link, it may help you: http://stackoverflow.com/questions/22858491/entity-framework-remove-object-with-foreign-key-preserving-parent – mako Apr 02 '17 at 02:26