ASP.NET MVC / EF4 / POCO / Repository - How zu Aktualisieren Beziehungen?
Ich habe eine 1..* Beziehung zwischen Abgeben und Empfehlungen.
Den relevanten Teil meiner Modell (das ist auch der POCO zugeordnet EF4):
public class Review
{
public ICollection<Recommendations> Recommendations { get; set; }
}
Auf eine Bearbeiten-Ansicht -, ich vertrete die Empfehlungen als eine Reihe von Checkboxen.
Wenn ich versuche fügen Sie eine neue Empfehlung als Teil der Bearbeitung der Beurteilung (e.g prüfen Sie ein anderes Feld), nichts ist passiert - und ich weiß warum...
Ich den "stub-Technik" aktualisieren mein Entitäten - e.g i erstellen Sie eine Entität mit dem gleichen Schlüssel, befestigen Sie es an der Grafik, dann tun ApplyCurrentValues
. Dies funktioniert aber nur für Skalare Eigenschaften, nicht für Navigations-Eigenschaften.
Fand ich diese StackOverflow-Frage die sieht gut aus, aber ich bin versucht, herauszufinden, wie man diese Arbeit mit POCO-s/Repository (und ASP.NET MVC - Einfamilienhaus-Kontext).
So, ich bin mit der POCO ist, review.Recommendations
ist ein ICollection<Recommendation>
, so kann ich das nicht review.Recommendations.Attach
. Ich bin nicht mit Self-Tracking Entitäten, also muss ich manuell arbeiten mit dem Diagramm/ändern tracking -, die bisher nicht ein problem bis jetzt.
So können Sie visualisieren das Szenario:
Kritik:
- Empfehlungen (
ICollection<Recommendation>
):- RecommendationOne (
Recommendation
) - RecommendationTwo (
Recommendation
)
- RecommendationOne (
Wenn ich auf der Bearbeiten-Ansicht, zwei der Kästchen sind bereits geprüft. Die Dritte (die RecommendationThree) ist deaktiviert.
Aber wenn ich überprüfen, dass das Feld, das obige Modell wird:
Kritik:
- Empfehlungen (
ICollection<Recommendation>
):- RecommendationOne (
Recommendation
) - RecommendationTwo (
Recommendation
) - RecommendationThree (
Recommendation
)
- RecommendationOne (
Deshalb muss ich anfügen RecommendationThree der graph als neue Entität.
Brauche ich hidden-Felder zu vergleichen mit den geposteten Daten der vorhandenen Person? Oder sollte ich speichern der Entität im TempData und vergleichen Sie die gebuchte Person?
BEARBEITEN
Um Verwirrung zu vermeiden, hier der gesamte app-stack nennen:
ReviewController
[HttpPost]
public ActionResult Edit(Review review)
{
_service.Update(review); //UserContentService
_unitOfWork.Commit();
}
UserContentService
public void Update<TPost>(TPost post) where TPost : Post, new()
{
_repository.Update(post); //GenericRepository<Post>
}
GenericRepository - als GenericRepository<Post>
public void Update<T2>(T2 entity) where T2 : class, new()
{
//create stub entity based on entity key, attach to graph.
//override scalar values
CurrentContext.ApplyCurrentValues(CurrentEntitySet, entity);
}
So, die Update
(oder Add
oder Delete
) Repository-Methoden aufgerufen werden muss für jede Empfehlung, je nachdem, es ist neu/geändert/gelöscht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vielleicht brauche ich mehr Kontext, aber was ist falsch mit:
?
Antwort auf den Kommentar:
Ok, so was ist falsch mit
oder
Letzten Satz? Du meinst die zwei Fragen?
Dies sollte nicht schwer sein überhaupt.
Zusammenfassen, meine Antwort, die ich denke, man tut Dinge, die "der harte Weg" und sollte wirklich der Fokus auf das posting-Formular Werte, die entsprechen, um die CRUD-Aktion Ihr versuchen zu erreichen.
Wenn eine neue Entität kommen könnte in der gleichen Zeit wie Ihre bearbeiteten Objekte, die Sie sollten wirklich Präfix Sie anders, so dass das Modell binder können, greifen es auf. Auch wenn Sie mehrere neue Elemente, die Sie verwenden können, die gleichen [0] syntax nur Präfix-Feld "name" mit Neuen oder etwas.
Viele Male in diesem Szenario können nicht Sie verlassen sich auf Entity Frameworks, graph-Funktionen, weil das entfernen einer Einheit aus einer Sammlung, die nie bedeutet, es sollte festgelegt werden, für die Löschung.
Wenn die form ist unveränderlich, Sie könnten auch versuchen, die generized Anhängen-Funktion aus der ObjectSet:
Tonnen von Möglichkeiten, aus dieser. Vielleicht könnten Sie veröffentlichen Sie Ihre controller-und view-code?
ApplyCurrentValues
.Attach(review)
wird, ändern Sie nur Skalare Werte - nicht die Empfehlung.ApplyCurrentValues
nur vergleicht alle Eigenschaften. ich muss die Logik für Zusammenhänge. arggh. vielen Dank für deine Hilfe, aber ich werde weiter arbeiten und hier wieder ein edit-sobald ich Fortschritte.Ich angenommen habe @jfar die Antwort, denn er setzte mich auf den richtigen Weg, aber dachte, ich würde hinzufügen, hier eine Antwort für andere Menschen davon profitieren.
Der Grund, warum die Beziehungen waren nicht immer aktualisiert ist aus den folgenden Gründen:
1) Komplett abgeschaltet Szenario. ASP.NET = staatenlos, neuen Kontext newed jede HTTP-Anfrage.
2) Bearbeitet Entität erstellt von MVC (Modell-Bindung), nicht aber bestehende graph.
3) Bei der Verwendung von POCO ist kein tracking durchführen
.Attach
auf Organisation hinzufügen, um die Grafik, sondern die Person und jedes Kind von Beziehungen werden Unverändert.4) ich benutze die stub-Einheit trick und
ApplyCurrentValues
update der entity, aber das funktioniert nur für Skalare Eigenschaften, nicht navigational lieben.Also - um die oben genannten arbeiten, ich müsste ausdrücklich festgelegt, die
EntityState
für das Objekt (das passiert automatisch, weil derApplyCurrentValues
), und auch die Navigations-Eigenschaften.Und es ist das problem - wie kann ich wissen wenn die Navigations-Eigenschaft wurde Hinzugefügt/geändert/gelöscht? Ich habe kein Objekt zum Vergleich zu - nur eine Person, die ich kenne, war "bearbeitet", aber ich weiß nicht was bearbeitet wurde.
So dass die Lösung am Ende war dieses:
Das ist es. Ich Brauch nicht mal meine
_service.Update
Methode - da brauche ich nicht die stub-trick nicht mehr - da die rezension ist in der Grafik mit dem Abruf, undApplyCurrentValues
wird ersetzt durchTryUpdateModel
.Nun natürlich - das ist nicht ein Parallelität Beweis Lösung.
Wenn ich laden Sie die Review-Ansicht Bearbeiten, und bevor ich auf "Absenden" jemand anderes ändert sich die Beurteilung, sind meine änderungen verloren gehen könnten.
Glücklicherweise habe ich einen "last-in-wins" Parallelität Modus, so dass es nicht ein Problem für mich.
Ich Liebe POCO ist, aber Mann, sind Sie ein Schmerz, wenn Sie die Kombination eines stateless environment (MVC) und keine Veränderung tracking.
TryUpdateModel
überlastung. Das oben ist nur ein einfaches Beispiel.Added
eventho es Sie schon gibt!Arbeiten mit getrennten Objekt-Graphen ist mein Favorit Nachteil der EF. Einfach pain in the ass. Zuerst müssen Sie sich mit es auf Ihrem eigenen. EF wird nicht helfen Sie mit ihm. Es bedeutet, dass zusätzlich zu
Review
Sie auch haben, senden Sie einige Informationen über änderungen. Wenn Sie anfügenReview
Kontext setzt esReview
alleRecommendation
und alle Beziehungen zuUnchanged
Zustand.ApplyCurrentValues
funktioniert nur für Skalare Werte, wie Sie bereits gefunden haben. So nehmen Sie Ihr zusätzliche Informationen über änderungen und stellen Beziehungen zuAdded
mithilfeObjectContext.ObjectStateManager.ChangeRelationshipState
.Ich persönlich gab sich mit diesem Ansatz, und ich bin be-graph-Objekt aus DB erste Zusammenführung meiner änderungen in den angeschlossenen Graphen und speichern Sie es.
Antwortete ich, ähnliche Frage tiefer hier.
ChangeRelationshipState
Weigerung, die Arbeit mitEntityState.Modified
habe ich auch aufgegeben und aktiviert Fremdschlüssel-Eigenschaften. Ihre blog post war eine interessante Lektüre.