2 Stimmen

ASP.NET MVC3 und Entity Framework v4.1 mit Fehler Ein Entitätsobjekt kann nicht von mehreren Instanzen von IEntityChangeTracker referenziert werden

Wenn ich derzeit ein Produkt in meinen Warenkorb lege, wird die Aktion "Hinzufügen" meines CartController wird aufgerufen mit der orderEntryDisplayViewModel (das Objekt der Auftragszeile).

    [HttpPost]
    public RedirectToRouteResult Add(Cart cart, OrderEntryDisplayViewModel orderLine)
    {
        if (!ModelState.IsValid)
        { return RedirectToAction("Display", "OrderEntry", new { Product = orderLine.Line.PartNum }); }
        CompleteProduct product = null;
        orderLine.Line.RequestedShipDate = orderLine.RequestedShipDate;
        if (orderLine.Line.NewMyPartNum != null)
        { orderLine.Line.MyPartNum = orderLine.Line.NewMyPartNum; }
        try
        {
            product = _inventoryRepo.FetchByPartNum(orderLine.Line.PartNum, User.Identity.Name);
            orderLine.Line.Product = product;
            cart.AddItem(orderLine.Line);
            //_cartRepo.Save();
        }
        catch (DbUpdateException e)
        { throw; }
        catch
        {
            ModelState.AddModelError("", "Problem adding part to cart");
            return RedirectToAction("Index", new { returnUrl = Url.Action("Index", "OrderEntry") });
        }
        return RedirectToAction("Index", new { returnUrl = Url.Action("Index", "OrderEntry") });
    }

Bevor sie erreicht wird, muss die CartModelBinder erstellt oder holt den Einkaufswagen aus der Sitzung.

public class CartModelBinder : IModelBinder
{
    private const string sessionKey = "Cart";

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        CartRepository cartRepo = new CartRepository();
        Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
        if (cart == null)
        {
            cart = cartRepo.CreateCart(true);
            cartRepo.DetachCart(cart);
            controllerContext.HttpContext.Session[sessionKey] = cart;
            cartRepo.AttachCart(cart);
        }
        else
        { cartRepo.AttachCart(cart); }
        return cart;
    }
}

Wenn in der Sitzung noch kein Einkaufswagen existiert, wird ein neuer mit dem Befehl CartRepository CreateCart Methode, die dann den neu erstellten Einkaufswagen zum Kontext hinzufügt.

    public Cart CreateCart(bool saveCart = false)
    {
        Cart cart = new Cart();
        context.Carts.Add(cart);
        if (saveCart)
        { context.SaveChanges(); }
        return cart;
    }

Bevor ich das Cart-Objekt der Sitzung hinzufüge, löse ich es aus dem Kontext mit CartRepository DetachCart , fügen Sie sie der Sitzung hinzu und fügen Sie sie dann wieder dem Kontext hinzu.

public void DetachCart(Cart cart)
{
    ((IObjectContextAdapter)context).ObjectContext.Detach(cart);
}

En CartRepository erhält den Kontext von ContextHelper :

public static class ContextHelper
{
    public static InsideIIMAKContext InsideIIMAK
    {
        get
        {
            if (HttpContext.Current.Items["InsideIIMAKContext"] == null)
            { HttpContext.Current.Items.Add("InsideIIMAKContext", new InsideIIMAKContext()); }
            return (InsideIIMAKContext)HttpContext.Current.Items["InsideIIMAKContext"];
        }
    }

Si CartModelBinder einen Wagen in der Sitzung findet, versucht er, den Wagen über die CartRepsitory Methode AttachCart .

    public void AttachCart(Cart cart)
    {
        context.Carts.Attach(cart);
    }

Am Ende der Aktion Hinzufügen in der Datei CartController Ich leite zur Index-Aktion um, um die Warenkorbansicht anzuzeigen. Die Index-Aktion erfordert auch das Cart-Objekt, also CartModelBinder wird ein zweites Mal aufgerufen und ruft dieses Mal die CartRepository AttachCart Methode. Mein Fehler tritt bei der AttachCart Methode

"Ein Entitätsobjekt kann nicht von mehreren Instanzen von IEntityChangeTracker referenziert werden."

Ich habe dieses Problem eine gute Menge recherchiert und es scheint nicht, dass ich eine Situation haben, wo ich das Warenkorb-Objekt zu zwei Instanzen des Kontextes hinzufügen, wie scheint oft der Grund für den Fehler sein. Es scheint fast so, als ob das in der Sitzung gespeicherte Cart-Objekt mit Tracking-Informationen geändert wird, so dass EF beim Versuch, es in der nächsten HTTP-Anfrage anzuhängen, denkt, dass es an einen aktiven Kontext angehängt ist, aber in Wirklichkeit ist es der Kontext aus der vorherigen Anfrage. Ich habe ein Forum gefunden, in dem vorgeschlagen wurde, das Entity-Objekt zu lösen, bevor es der Sitzung hinzugefügt wird, aber ich habe das getan und habe immer noch das gleiche Problem.

Ich hoffe, ich habe bei dieser Erklärung nichts übersehen.

ANTWORT Dank an Mark Oreta

    public void DetachCart(Cart cart)
    {
        var objectContext = ((IObjectContextAdapter)context).ObjectContext;
        objectContext.Detach(cart.Customer);
        foreach (var item in cart.Lines)
        { objectContext.Detach(item); }
        objectContext.Detach(cart);
    }

1voto

Mark Oreta Punkte 10316

Wenn Sie den Wagen in die Sitzung stellen, lösen Sie dann das Objekt aus diesem Kontext? Entitätsobjekte tragen den Kontext mit sich, daher müssen Sie ihn vor dem Hinzufügen explizit abkoppeln.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X