0

So I'm currently developing a WPF app which is linked to a database, and I've got a method in which I have a for-each loop that iterates through each item added to my basket and adds the items to the database so that I can print a receipt.

When I have an item in the middle of the basket, that has been sold out, I want to stop the for-each loop (not iterate in any other items) and display a message explaining that the item is out of stock, so that the user can edit the basket and remove that item, and then proceed to print the receipt again.

When this case happens, I get an error because the receipt ID and some of the items have already been Added (dbContext.Add(item)) so when the user clicks print receipt again (After amending the sold-out item), when I call save, I've got added data on the entity, that has not been added.

Is there any way of detaching everything that has not been saved if one item is out of stock ??

Error Message:

UpdateException: Unable to determine the principal end of the 'Context.FK_Receipt_Item_Receipt' relationship. Multiple added entities may have the same primary key.

public void AddToDatabase()
{
    boolean canPrintReceipt = true;

    Receipt receipt= new Receipt
    {
        ID = Guid.NewGuid()
    };

    Db.Receipts.Add(receipt);

    foreach (KeyValuePair<string, int> entry in Basket)
    {
        Item item= new Item();
       
        if // item is out of stock
        {
            canPrintReceipt = false;
            break;
        }
        else //Add new Item
        {
            ...
            ...
            Db.Items.Add(item);
        }

        Receipt_Item receiptItems = new Receipt_Jugada
        {
            ReceiptID = receip.ID,
            ItemID = item.ID,
            ...,
            ...
        };
        Db.Receipt_Items.Add(receiptItems);
    }

    if (canPrintReceipt)
    {
        Db.SaveChanges();
        Basket.Clear();
    }
}
atiyar
  • 7,762
  • 6
  • 34
  • 75
TonyBP
  • 83
  • 3
  • Does this answer your question? [Entity Framework 6 transaction rollback](https://stackoverflow.com/questions/22486489/entity-framework-6-transaction-rollback) – Lukasz Szczygielek Oct 16 '20 at 00:17

1 Answers1

0

Your best bet is to probably use a transaction.

Start a transaction. If you hit an out of stock item, rollback the transaction, and you can run the process again after the out of stock item has been removed from the cart.

If everything is in stock and everything works you can commit the transaction and everything will be saved to the database.

Here is a link to the basics.

Good Luck!

Elpenor
  • 16
  • 1
  • I tried implementing the method using transactions, but I don't know if there is something missing in my code, but I still keep getting the same error message. When a transaction is not committed (because it had an out of stock item), I RollBack, update the basket and run my code again, then my transaction will fail on the context.SaveChanges() UpdateException: Unable to determine the principal end of the ''Context.FK_Receipt_Item_Receipt' ' relationship. Multiple added entities may have the same primary key. – TonyBP Oct 16 '20 at 14:08
  • Ok, it looks like you might not be saving the receipt record before trying to add the items. Try adding a db.SaveChanges before the for loop and see if that helps. – Elpenor Oct 17 '20 at 00:50