Help understand the error of An entity object cannot be referenced by multiple instances of IEntityChangeTracker.


  • QA Engineer

    I'm trying to make an order, but there's a mistake.

    Ошибка источника: 
    

    Строка 63: if (order.ID_ORDER_BOOK == 0)
    Строка 64: {
    Строка 65: order = context.nameorder.Add(order);
    Строка 66:
    Строка 67: foreach (OrderLine line in order.OrderLines)

    That's what I'm trying to keep the order on.

      public void SaveOrder(order_book order)
    {
    if (order.ID_ORDER_BOOK == 0)
    {
    order = context.nameorder.Add(order);

            foreach (OrderLine line in order.OrderLines)
            {
                context.Entry(line.book).State
                    = EntityState.Modified;
            }
    
        }
        else
        {
            order_book dbOrder = context.nameorder.Find(order.ID_ORDER_BOOK);
            if (dbOrder != null)
            {
                dbOrder.DATE_DELIVERY = order.DATE_DELIVERY;
                dbOrder.DATE_ISSUE = order.DATE_ISSUE;
                dbOrder.CLIENT_ID = order.CLIENT_ID;
                dbOrder.EMPLOYEE_ID = order.EMPLOYEE_ID;
    
            }
        }
        context.SaveChanges();
    } 
    

    Class

     public class book
    {
    [Key]
    public int ID_BOOK { get; set; }
    public string NAME_BOOK { get; set; }
    public int? AUTHOR_ID { get; set; }
    public int PUBLISHING_HOUSE_ID { get; set; }
    public string YEAR_PUB { get; set; }
    public int CATEGORY_ID { get; set; }
    public int ISBN { get; set; }
    public int ISSN { get; set; }
    public int STATUS_ID { get; set; }
    public int STATE_ID { get; set; }
    public int LOCATION_ID { get; set; }
    public int GENRE_ID { get; set; }
    [ForeignKey("AUTHOR_ID")]
    public virtual author_books author_book { get; set; }
    [ForeignKey("GENRE_ID")]
    public virtual genre_book genre_book { get; set; }
    public virtual List<order_book> order_book { get; set; }
    public class order_book
    {
    [Key]
    public int ID_ORDER_BOOK { get; set; }
    public int? CLIENT_ID { get; set; }
    public int? EMPLOYEE_ID { get; set; }
    public string DATE_ISSUE { get; set; }
    public string DATE_DELIVERY { get; set; }
    public int? BOOK_ID { get; set; }
    [ForeignKey("BOOK_ID")]
    public virtual book book { get; set; }
    [ForeignKey("EMPLOYEE_ID")]
    public virtual employee employee { get; set; }
    [ForeignKey("CLIENT_ID")]
    public virtual Client Client { get; set; }
    public virtual List<OrderLine> OrderLines { get; set; }

    public class OrderLine
    {
    public int OrderLineId { get; set; }
    public order_book Order { get; set; }
    public book book { get; set; }
    public int Quantity { get; set; }

    }

    Web form

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Checkout.aspx.cs"
    Inherits="Library.Pages.Checkout"
    MasterPageFile="~/Pages/Lib.Master" %>

        <div id="checkoutForm" class="checkout" runat="server">
    <h2>Оформить заказ</h2>
    Пожалуйста, введите свои данные, и мы отправим Ваш товар прямо сейчас!

    &lt;div id="errors" data-valmsg-summary="true"&gt;
        &lt;ul&gt;
            &lt;li style="display:none"&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;asp:ValidationSummary ID="ValidationSummary1" runat="server" /&gt;
    &lt;/div&gt;
    
        &lt;h3&gt;&lt;/h3&gt;
        &lt;div&gt;
            &lt;label for="DATE_DELIVERY"&gt;D&lt;/label&gt;
            &lt;input id="DATE_DELIVERY" name="DATE_DELIVERY" runat="server" /&gt;
        &lt;/div&gt;
    
        &lt;h3&gt;&lt;/h3&gt;
        &lt;div&gt;
            &lt;label for="DATE_ISSUE"&gt;D&lt;/label&gt;
            &lt;input id="DATE_ISSUE" name="DATE_ISSUE" runat="server" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label for="CLIENT_ID"&gt;C&lt;/label&gt;
            &lt;input id="CLIENT_ID" name="CLIENT_ID" runat="server" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label for="EMPLOYEE_ID"&gt;E&lt;/label&gt;
            &lt;input id="EMPLOYEE_ID" name="EMPLOYEE_ID" runat="server" /&gt;
        &lt;/div&gt;
        &lt;h3&gt;Детали заказа&lt;/h3&gt;
        &lt;input type="checkbox" id="giftwrap" name="giftwrap" value="true" /&gt;
        Использовать подарочную упаковку?
    
    &lt;p class="actionButtons"&gt;
        &lt;button class="actionButtons" type="submit"&gt;Обработать заказ&lt;/button&gt;
    &lt;/p&gt;
    
    
    &lt;/div&gt;
    &lt;div id="checkoutMessage" runat="server"&gt;
        &lt;h2&gt;Спасибо!&lt;/h2&gt;
       Мы постараемся максимально быстро отправить ваш заказ   
    &lt;/div&gt;
    

    </div>

    And code-behind

    using System;
    using System.Collections.Generic;
    using Library.Models;
    using Library.Models.Repository;
    using Library.Pages.Helpers;
    using System.Web.ModelBinding;

    namespace Library.Pages
    {
    public partial class Checkout : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {
    checkoutForm.Visible = true;
    checkoutMessage.Visible = false;

        if (IsPostBack)
        {
            order_book myOrder = new order_book();
            if (TryUpdateModel(myOrder,
               new FormValueProvider(ModelBindingExecutionContext)))
            {
    
                myOrder.OrderLines = new List&lt;OrderLine&gt;();
    
                Cart myCart = SessionHelper.GetCart(Session);
    
                foreach (CartLine line in myCart.Lines)
                {
                    myOrder.OrderLines.Add(new OrderLine
                    {
                        Order = myOrder,
                        book = line.book,
                        Quantity = line.Quantity
                    });
                }
    
                new Repository().SaveOrder(myOrder);
                myCart.Clear();
    
                checkoutForm.Visible = false;
                checkoutMessage.Visible = true;
            }
        }
    }
    

    }
    }



  • Each context in the EF tracks changes in loaded objects - to keep them from challenge SaveChanges()♪ Therefore, an object cannot be linked to two contexts at the same time - otherwise it is unclear that it and associated objects from the context context1 It's supposed to happen when you call. context2.SaveChanges()

    What's going on with you:

    • You're uploading the object at some point. book from context 1. You're throwing in a session. You've got a session in InProc, so there's an original object that's not his showcase.
    • You create a new context 2. Create the Order, add to it OrderLine, which refers to the book.
    • Trying to tie order to context 2. This leads to the linking of OrderLine and book to context 2. The book is already tied to context1. Expession.

    How to fix (the lower the better option):

    • not to keep contextual objects in the session. BL border crossingscontext.Books.Detach(someBook)) Relocate (Attach) in order.
    • or: Not to keep it in the session at all! Your book is in the base. There's no point in keeping it in the session.
    • or: https://ru.stackoverflow.com/a/424111/177221 For example, in your stap, the basket will be lost when the application is reset. In your case, you should use a bag to store the id books in the basket.



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2