SharePointCommunity
Die deutschsprachige Community für SharePoint, Microsoft 365, Teams, Yammer und mit Azure

SP2010 Ergeignisempfänger - Konflikt beim Speichern in ItemUpdated, in ItemAdded funktioniert identischer Code

bewertet von 0 Usern
Nicht beantwortet Dieser Beitrag hat 0 Geprüfte Antworten | 1 Antwort | 1 Follower

Top-50-Beitragsschreiber
282 Beiträge
MStel erstellt in 6 Jun 2019 15:48

Hallo,

ich habe zwei Listen mit vielen Spalten in meinem System. In einigen davon  benötige ich berechnete Daten. Da das calculated Feld mir für den Umfang zu kompliziert einzurichten und nicht umfassend genug ist,  und ein Timerjob nicht schnell genug greift (ich es davon abgesehen auch nicht schön fände, diesen jede Minute laufen zu lassen), habe ich mich für einen Ereignisempfänger entschieden, welchen ich in Visual Studio 2012 in C# geschrieben habe.

Zunächst habe ich das ganze für die ItemAdded Methode gebaut und geprüft, ob dieser auslöst, nachdem ein Listenelement einer benutzerdefinierten Liste hinzugefügt wird.
Das alles hat sehr gut funktioniert, sobald ich in einer x beliebigen Liste ein Element hinzufüge. wird die entsprechende Funktionalität ausgeführt und das ganze geht auch bei tausenden Datensätzen so performant, dass ich diesbezüglich nicht optimieren muss.

Zum Code an sich:
Ich habe mir zunächst mit mehreren N zu N schleifen über die SP LIsten inmemory ein Struct zusammengebaut(wo ich nur lesend über die eigentlichen Listen gehe ohne etwas zu verändern), wie ich es quasi im Zielsystem haben möchte und anschließend in einem Vorgang die Datensätze in den SP Listen die sich von meinem inmemory struct unterscheiden aktualisiert.

Hat wie gesagt auch alles einwandfrei geklappt, bis ich dann jedoch mit dem ItemUpdated EventHandler angefangen habe. Da sich die Funktionalität die dort stattfindet (mit ausnahme der Base Item Properties in dem Fall) nicht mit der aus der ItemAdded Methode unterscheidet war ich einfach mal so frei meinen Code zu kopieren und in der ItemUpdated Methode einzufügen.

Natürlich bin ich mit Vorsicht rangegangen und habe mir im breakpoint angesehen ob die Inmemory Objekte korrekt gefüllt sind. Als ich das verifiziert habe und einige Schritte weitergegangen bin habe ich dann die Meldung "Konflikt beim Speichern" erhalten.

Und zwar tritt die Meldung genau in der Zeile auf, in der ich versuche das SPListItem zu updaten.
Das Listelement, welches gerade bearbeitet wird,  wird zwar korrekt aktualisiert, da ich aber jedesmal wenn ich in einem x beliebigen Element etwas ändere auch alle anderen Elemente der Liste durchlaufen und potenziell ändern muss, kann ich diese ListItem.Update Zeile auch nicht auskommentieren. Testhalber habe ich das ganze natürlich gemacht, dann erhalte ich zwar keinen Fehler, aber andere Elemente erhalten logischerweise auch nicht ihre werte, obwohl sie das beim itemAdded tun.

Da ich befürchtet habe, dass bei einem Add auch zwangsläufig ein Update geschieht, und vielleicht beide Eventhandler gleichzeitig versuchen etwas zu machen und sich in die Quere kommen, habe ich die ItemAdded Methode erstmal rausgenommen und mich aufs Update fokussiert.
Das Ergebnis war dasselbe.

Sobald ich im Ereignisempfänger ItemUpdated versuche, andere Elemente in der Liste zu aktualisieren erhalte ich den Konflikt beim Speichern. Das ist allerdings notwendig, um alle Funktionen abzubilden.

Das einzige was ich noch nicht versucht habe, wäre zu erzwingen dass Akiton A fertig ist bevor B anfängt oder für jeden Wert der aktualisiert wird einen eigenen Empfänger zu erstellen. Denkt ihr, dass könnte die Ursache sein?
Oder ist so etwas wie ich es vor habe generell nicht vorgesehen?

Also nur damit ihr grob eine Idee bekommt was ich vor habe;
Ihr habt eine Liste mit Arbeitern und eine Liste mit Stunden, sobald bei den Stunden eine Änderung vorliegt, erhält der Arbeiter in der Zeile Stundenübersicht einen aktualisierten wert.
Da das natürlich triggern soll, sobald Stunden hinzukommen oder geändert werden, als auch wenn ein neuer arbeiter angelegt wird (damit dieser den wert 0 erhält) müssen diese Listen quasi Hand in Hand arbeiten um immer aktuell zu bleiben.

Das ist jetzt wirklich sehr vereinfacht und in der Praxis deutlich komplizierter, aber spiegelt das ganze eventuell etwas besser wieder.

Ich wäre um Ideen wie man diesem Problem auf den Grund gehen könnte sehr dankbar, weil die eigentliche Fehlermeldung und warum diese auftritt ist halt mehr als klar und deutlich verständlich.

Danke schon mal im voraus

MFG

Alle Antworten

Top-10-Beitragsschreiber
19.014 Beiträge

Ich habe Deinen sehr ausführlichen Text nur überflogen und daher auch nur ein paar allgemeine Tips.

Grundsätzlich solltest Du in einem EventReceiver wirklich nur das Element aktualisieren, das auch das Event ausgelöst hat. Wenn Du auch andere aktualisierst, kannst Du ganz schnell Zirkelbezüge und damit Endlosschleifen schaffen.

Du mußt beachten, daß ein Update in ItemAdded auch sofort ein ItemUpdated auslöst.

Wenn möglich sollte man seine Änderungen in ItemAdding bzw. ItemUpdating machen, weil dann kein zusätzliches Update notwendig ist und damit keine Nebeneffekte ausgelöst werden können. Das sollte man aber nur tun, wenn "es schnell geht", also wenn keine zusätzlichen Abfragen auf andere Listen o.ä. notwendig ist.

Man kann in ItemUpdating prüfen, welche Felder sich tatsächlich geändert haben und damit herausfinden, ob ein weiteres Update durch den Code überhaupt notwendig ist. Allerdings muß man dann seinen Code mit dem in ItemUpdated synchronisieren.

Und zu guter Letzt: man kann im Code mit EventFiringDisabled/EventFiringEnabled unterdrücken, daß weitere Events ausgelöst werden. Das ist aber wirklich mit Vorsicht zu behandeln und immer nur ganz kurz. Also EventFiringDisabled - item.Update() - EventFiringEnabled. Und immer mit try/catch/finally sicherstellen, daß es auch wirklich wieder enabled wird.

Viele Grüße
Andi
af @ evocom de
Blog
Seite 1 von 1 (2 Elemente) | RSS