2009-04-11 9 views
1

Ich bin auf der Lernkurve der Silverlight-Trail. Da ich ein datenzentrischer Entwickler bin, habe ich natürlich den ADO.NET Data Services-Client auf dem Weg abgeholt. Ich kratze mich über ein realistisches Szenario und kann keine Hilfe in Dokumentation, Blogs usw. finden.Client-seitige Entity-Erstellung mit zugehörigen Codetabellen

Ich habe eine komplexe Tutor-Entität mit verwandten Entitätsgruppen für Adressen, Telefonnummern und E-Mail-Adressen . Ich habe auch ein paar andere Sets wie Fächer und Zertifizierungen. Zusammen mit all dem kommen Fremdschlüssel zu Lookup-Tabellen für Dinge wie StatusCodes, AddressTypes (wie Home, Business usw.), EmailTypes und so weiter. All dies ist in einem edmx in meinem Model-Projekt gekapselt. Hier ist ein Teil der Struktur.

alt text

In Silver ich ein Usercontrol habe, dass ein Dateneingabeformular für diesen Lehrer ist. Ich habe ein DTO-ähnliches Objekt für die Datenbindung an die TextBox-Steuerelemente des Clients erstellt. Alles ist gut, bis der Benutzer auf Speichern klickt.

Die Save-Routine erstellt und fügt einen Tutor und Person-Objekte hinzu und fügt sie dem DataServiceContext hinzu und verknüpft sie ordnungsgemäß. Wo ich in Schwierigkeiten bin, ist, dass ich eine verwandte Entität hinzufügen muss, die in dem Kontext in der Datenbank ALREADY wie Codetabellen gespeichert wird.

Zum Beispiel kann die Person mehrere Fachgebiete haben: Elementary Math, Elementary Science etc. Das TutorSubjectSet muss sich auf 3 andere Sets beziehen: Subjekt (zB Math), SubjectLevel (zB Elementary) und dann zum Tutor . Mein DTO hat eine Liste von kombinierten Subject_With_Level-Elementen, die eine Untermenge einer wahren kartesischen Auswahl darstellen (es gibt keine elementaren (Schul-) Kalküle, zumindest nicht dort, wo ich zur Schule gegangen bin :-). Diese Liste wird als Checkbox-Liste auf der Benutzeroberfläche angezeigt. Wenn der Benutzer auf Speichern klickt, werden die überprüften Elemente abgerufen, und ich versuche, die kombinierten Werte für Subject_With_Level.SubjectId und .SubjectLevelId anhand der Codetabellen mit diesen Werten zu ermitteln.

Hier ist ich verloren. In einer serverseitigen Funktion wäre ich in Ordnung, weil ich diese Nachschlagevorgänge inline durchführen und die Entität sofort abrufen kann. Wie erhalte ich in einer Async-Situation die zugehörigen Entitäten, während ich damit beschäftigt bin, das Personendiagramm zusammenzusetzen? Das Ausführen eines Async-Anrufs in der Mitte des Speichervorgangs funktioniert nicht.

Ich habe verschiedene Dinge ausprobiert: Ich habe versucht, sie ein Ad-hoc-Nachbildung des SubjectLevel die Subject_With_Level.SubjectLevelId mit und Befestigung, die mit dem Kontext, wie folgt:

 



public static SubjectLevel MakeFakeSubjectLevelFor(TutoringEntities ctx, Subject_With_Level subjectAndLevel) 
{ 
    var subjectLevel = new SubjectLevel() 
         { 
         SubjectLevelId = subjectAndLevel.SubjectLevelId, 
         Description = subjectAndLevel.SubjectLevel, 
         EffectiveDate = DateTime.Now, 
         EnteredBy = "", 
         EnteredDate = DateTime.Now, 
         Type = subjectAndLevel.SubjectLevel 
         }; 
    try { ctx.AttachTo("SubjectLevelSet", subjectLevel); } 
    catch { //this tries to catch situations where the level (eg. Elementary) has already been created } 
    return subjectLevel; 
} 


 

Dieser Ansatz für Situationen, in denen es funktioniert sind keine Duplikate (es hat auch den Vorteil, dass ich keinen zusätzlichen Anruf tätigen muss.) Zum Beispiel gibt es in Adressen nur eine Heimatadresse (ich habe eine ähnliche Funktion: MakeAFakeAddressTypeFor()). Sie werden feststellen, dass ich einen try/catch habe, der den Fehler abfängt, wenn die Elemente bereits in das SubjectLevelSet eingefügt wurden. Wenn das Element bereits eingefügt wurde und ich diesen Fehler gefunden habe, ist das zurückgegebene subjectLevel nicht an den Kontext gebunden. Ich erhalte einen Fehler, da das Objekt nicht verfolgt wird. Ich kann jedoch ein vorhandenes subjectLevel nicht abrufen, ohne eine asynchrone Abfrage für das SubjectLevelSet auszustellen, selbst wenn es sich in meinem lokalen Kontext befindet.

Was möchte ich tun ist:


var lev = ctx.SubjectLevelSet.Where(l => l.SubjectLevelId == subjectAndLevel.SubjectLevelId).FirstOrDefault(); 
if(lev == null) 
    lev = Helpers.MakeFakeSubjectLevelFor(ctx, subjectAndLevel); 

aber ich erhalte: „Angegebene Methode wird nicht unterstützt“, die ich Mittel nehme ich die Abfrage Async zu tun haben, so bin ich wieder die gleiche Lage.

Ich habe auch versucht, eine Liste von SubjectLevels in der Loaded Event Delegate abrufen. Auf diese Weise hätte ich den Satz von SubjectElements zur Hand, wenn die Save-Taste gedrückt wird.Dasselbe Problem, ich muss einen Async-Anruf ausgeben, um eine Suche durchzuführen, selbst wenn ich es in der Hand habe. Ich habe versucht, die Liste durchzublättern, die ich benötigte, aber das gab mir eine Fehlermeldung, dass die Entität nicht vom Kontext verfolgt wurde.

Also ... klar verstehe ich das nicht und mache es falsch, aber ich kann keine praktischen Beispiele finden, die so etwas tun. Die How-To-Beispiele laden einfach Grundelemente in die zu speichernde Entität. Keine Beispiele, die ich gesehen habe, zeigen verwandte Entitäten und wie man sie findet. Ich könnte es einfach machen und nur ganzzahlige Werte für die codeId speichern und sie nicht über FKs beziehen, aber das wäre zu sehr ein Kompromiss.

Danke für jede Hilfe, die Sie mir zur Verfügung stellen können.

Antwort

0

Realistisch gesehen denke ich, dass Sie die Abfrage Async tun müssen, weil es zu lange dauert? Ist diese Annahme richtig? Wenn dies der Fall ist, sollten Sie untersuchen, was Sie mit der Abfrage selbst tun möchten. Ich finde immer, wenn ich das SQL schreiben kann, um genau die Daten zu bekommen, die ich will, dann kann ich vorwärts mit dem Schreiben des LINQ zu ihm vorwärts gehen (mit etwas wie LINQPad).

Zusätzlich können Sie auch eine SQL-Ansicht erstellen, die Ihr komplexes Diagramm "flacht". Stellen Sie dann im EF-Aktualisierungsassistenten sicher, dass Sie die Ansicht ausgewählt haben. Auf diese Weise können Sie jedes Mal, wenn Sie dieses benutzerdefinierte komplexe DTO erstellen, einfach eine serverseitige where-Klausel ausgeben und Ihre Werte dort auffüllen.

Wenn ich im linken Feld bin, lassen Sie es mich wissen, ich habe umfangreiche Erfahrung mit EF in sehr komplexen Geschäftsdaten Objekt Szenarien und ich bin mehr als wahrscheinlich, Ihre Situation falsch zu lesen.

Ich denke, die Leute auf SO haben nicht geantwortet, weil es lang war und sie auf ein Kopfgeld gehofft hatten, nur eine Vermutung.