ADO.Net Entity Framework Ein Entitätsobjekt kann nicht von mehreren Instanzen von IEntityChangeTracker referenziert werden

ado.net c# entity-framework

Frage

Ich versuche, meinen Kontakt zu speichern, der Verweise auf ContactRelation (nur die Beziehung des Kontakts, verheiratet, ledig usw.) und Land enthält. Jedes Mal, wenn ich versuche, meinen Kontakt zu speichern, der gültig ist, wird die Ausnahme "ADO.Net Entity Framework Ein Entitätsobjekt kann nicht von mehreren Instanzen von IEntityChangeTracker referenziert"

public Contact CreateContact(Contact contact)
{
    _entities.AddToContact(contact); //throws the exception
    _entities.SaveChanges();
    return contact ;
}

Ich verwende ein lose gekoppeltes MVC-Design mit Services und Repositorys. Ich habe viele Beiträge zu dieser Ausnahme gelesen, aber keine gibt mir eine funktionierende Antwort ...

Danke, Peter

Akzeptierte Antwort

[Aktualisieren]
Da L2E verwendet wird, müssen Sie zuerst alle verknüpften Objekte speichern, bevor Sie das Hauptobjekt speichern können. Was sinnvoll ist, sonst würden Sie (in meinem Beispiel) einen Künstler ohne Kontaktobjekt erstellen. Dies ist vom Datenbankentwurf nicht zulässig.
[/Aktualisieren]

Hier ist meine Implementierung, die funktioniert hat.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Artist artist, [Bind(Prefix = "Contact")] Contact contact, [Bind(Prefix = "Country")] Country country, [Bind(Prefix = "ContactRelationship")] ContactRelationship contactRelationship)
{
    ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name), "ID", "Name");
    ViewData["ContactRelationships"] = new SelectList(new ContactRelationshipService(_msw).ListContactRelationships().OrderBy(c => c.ID), "ID", "Description");

    country = _countryService.GetCountryById(country.ID);
    contact.Country = country;
    contactRelationship = _contactRelationshipService.GetContactRelationship(contactRelationship.ID);
    contact.ContactRelationship = contactRelationship;
    if(_contactService.CreateContact(contact)){
        artist.Contact = contact;
        if (_service.CreateArtist(artist))
            return RedirectToAction("Index");        
    }
    return View("Create");
}

Und dann in meinem ContactRepository:

public Contact CreateContact(Contact contact)
{
    _entities.AddToContact(contact); //no longer throws the exception
    _entities.SaveChanges();
    return contact ;
}

Ich habe auch auf dieser Website festgestellt, dass es am besten ist, den gleichen Kontext in der gesamten Anwendung zu behalten. Daher verwende ich jetzt eine spezielle Datenklasse:

Rick Strahl und Samuel Maecham haben mich gelehrt, dass Sie Ihren Datenkontakt pro Benutzer und Anfrage beibehalten sollten. Was bedeutet, es für Webanwendungen in den HttpContext zu setzen. Lesen Sie hier alles darüber

public class Data
{
    public static MyDBEntities MyDBEntities
    {
        get
        {
            if (HttpContext.Current != null && HttpContext.Current["myDBEntities"] == null)
            {
                HttpContext.Current["myDBEntities"] = new MyDBEntities ();
            }
            return HttpContext.Current["myDBEntities"] as MyDBEntities;
        }
        set { 
            if(HttpContext.Current != null)
                HttpContext.Current["myDBEntities"] = value; 
        }
    }
}

Beliebte Antwort

Ich habe dies bereits zuvor gesehen. Möglicherweise müssen Sie das Referenzfeld vor dem Speichern in einen EntityKey konvertieren und anschließend laden, nachdem es gespeichert wurde. Versuchen Sie stattdessen diesen Code:

public Contact CreateContact(Contact contact){
    contact.ConvertContactRelationToReference();
    _entities.AddToContact(contact); 
    //throws the exception
    _entities.SaveChanges();
    contact.ContactRelation.Load();
    return contact;
}

public partial class Contact
{
  public void ConvertContactRelationToReference()
  {
    var crId = ContactRelation.Id;
    ContactRelation = null;
    ContactRelationReference.EntityKey = new EntityKey("MyEntities.ContactRelations", "Id", crId);
  }
}

Natürlich muss dieser Code in Abhängigkeit von Ihrer genauen Datenbankstruktur geändert werden.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum