Entwickler-Ecke
Datenbanken (inkl. ADO.NET) - Entity-Framework: Konfiguration der Zuordnungsschicht
T-Stueck - Mi 05.08.09 12:06
Titel: Entity-Framework: Konfiguration der Zuordnungsschicht
Hallo,
ich bräuchte Hilfe/Tips bei der Erstellung der Zuordnungsschicht des Entity-Framework Modells.
Per Default wird ja eine 1:1 Zuordnung erstellt so dass die vom EF erstellten Objekte unmittelbar aus den DB-Tabellen hervorgehen.
Ich würde gern die Möglichkeit nutzen die Objekte unabhängig von der Tabellenstruktur in der DB zu definieren, was ja im EF auch möglich sein soll.
Dazu habe ich ein kleines Beislpielprojekt mit zwei Tabellen erstellt. Die eine "Names" enthält nur eine UserID (Int32) und den Nachnamen (String).
Die Zweite "Prenames" enthält nur die UserID (Int32) und den Vornamen (String).
Ich möchte nun die Zuordnungsschicht so definieren, dass ich in der konzeptionellen Schicht ein Objekt "Fullnames" erhalte, dass UserID, Vorname und Nachnamen enthält.
Dazu habe ich in der Design-Ansicht der edmx-Datei ein neues Objekt "Fullnames" erstellt mit den Eigenschaften UserID, Name, Prename und in den Zuordnungsdetails die Tabellen Names und Prenames zugeordnet. (siehe Anhang localDBModel01.PNG)
Jetzt habe ich im Fehler-Fenster immer drei Fehler der Art:
"Fehler 11008: Die Zuordnung 'NamesPrenames' ist nicht zugeordnet."
"Fehler 11008: Die Zuordnung 'FullnamesNames' ist nicht zugeordnet."
"Fehler 11008: Die Zuordnung 'FullnamesPrenames' ist nicht zugeordnet."
Wo soll ich die Associations zuordnen und wie?
Meine Form enthält nur eine DataGridView mit folgendem Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| private void Form1_Load(object sender, EventArgs e) { ctx = new SimpleDB01Entities(); ObjectQuery<Fullnames> fn = ctx.Fullnames; try { this.dataGridView1.DataSource = fn; } catch (Exception ex) { MessageBox.Show(ex.Message); } } |
Das Erstellen des Projektes ist erfolgreich, nur beim Ausführen bekomme ich den Fehler:
"Fehler bei der Vorbereitung der Befehlsdefinitionen. Details finden Sie in der internen Ausnahme."
und die dataGridView Form ist leer.
Welche interne Ausnahme ist hier gemeint? Im System-Log steht nichts drin und andere Fehlermeldungen sehe ich nicht.
Was mache ich falsch? Auch nach langem Lesen der MSDN zum EF bin ich ratlos.
Kann mir bitte jemand einen Tipp geben oder einen Link, Hinweis o.ä.?
Vielen Dank im Voraus.
danielf - Do 06.08.09 11:53
Hallo,
wieso willst du es so machen?
Du kannst ja auch einfach eine Zuordnung von Nachname auf Vorname machen.
Den Vornamen bzw. die Vornamen kannst du dann mit (Pseudo-Code bei 1:1 Beziehung):
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var d = (from c in DataEnties select *).Include("Vorname");
foreach (Nachname n in d) { Console.WriteLine(string.Format("{0}, {1}", d.Name, d.Vorname.Name)); } |
bzw. bei 1:n beziehung mit Iterator über die Vornamen.
Gruß
Daniel
T-Stueck - Do 06.08.09 12:52
Hallo Daniel,
vielen Dank erstmal für Deine Antwort.
danielf hat folgendes geschrieben : |
wieso willst du es so machen?
|
Nun, es war meine erste Idee und mein Verständnis der Art und Weise wie die Zuordnung im EDM erfolgt. Ich bin für andere Vorschläge offen.
danielf hat folgendes geschrieben : |
Du kannst ja auch einfach eine Zuordnung von Nachname auf Vorname machen.
|
Wenn ich die in der Design-Ansicht erstelle wird Sie aber nur in der konzeptionellen Schicht angelegt. Das resultiert dann in Fehlermeldungen à la "Die Zuordnung '...' ist nicht zugeordnet."
Ich muss also die Zuordnung auch in der Zuordnungsschicht und evtl. auch in der Datenbank-Schickt erstellen - manuell :-(. Daran bin ich bis jetzt gescheitert. Ich bekomme Fehlermeldungen die ich nicht so recht interpretieren kann:
"Fehler 3021: Problem beim Zuordnen des Fragments ab Zeile 74: Jede der folgenden Spalten in Tabelle Names ist mehreren Konzeptseiteneigenschaften zugeordnet:
Names.UserId ist <NamesPrenames.Names.UserId, NamesPrenames.Prenames.UserId> zugeordnet".
Ich habe folgenden Code in's edmx-File in der Mapping-Layer eingefügt (komplettes edmx wieder im Anhang):
<AssociationSetMapping Name="NamesPrenames" TypeName="SimpleDB01Model.NamesPrenames" StoreEntitySet="Names">
<EndProperty Name="Names">
<ScalarProperty Name="UserId" ColumnName="UserId" />
</EndProperty>
<EndProperty Name="Prenames">
<ScalarProperty Name="UserId" ColumnName="UserId" />
</EndProperty>
</AssociationSetMapping>
danielf hat folgendes geschrieben : |
Den Vornamen bzw. die Vornamen kannst du dann mit (Pseudo-Code bei 1:1 Beziehung):
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var d = (from c in DataEnties select *).Include("Vorname");
foreach (Nachname n in d) { Console.WriteLine(string.Format("{0}, {1}", d.Name, d.Vorname.Name)); } |
|
Das ist mir noch nicht ganz klar. Ich habe folgenden Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| static void Main(string[] args) { SimpleDB01Entities ctx = new SimpleDB01Entities(); ObjectQuery<Names> fn = ctx.Names;
var d = (from c in fn select "*"); foreach(string n in d) { Console.WriteLine(n); }
Console.WriteLine("Zum Beenden beliebige Taste Drücken"); Console.ReadKey(); } |
Der lässt sich zwar fehlerfrei übersetzen (bis auf den Mapping-Fehler), beim Ausführen bekomme ich aber eine "EntityCommandCompilationException".
Was mache ich noch falsch?
Danke und Gruss,
Gunther
danielf - Do 06.08.09 13:49
ich bin mir nicht sicher, aber
C#-Quelltext
1:
| var d = (from c in fn select "*"); |
hab ich so noch nicht gesehen. Versuch mal:
C#-Quelltext
1:
| var d = (from c in fn select c); |
Die Zuordnung musst du glaub so oder so in der DB machen mit PK u. FK.
Dann gibt es noch ein Fenster im Model Designer bei dem du die Felder mappen kannst (Dieses hab ich zuerst auch nicht gesehen).
T-Stueck - Do 06.08.09 15:28
Ich hab's:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| SimpleDB01Entities ctx = new SimpleDB01Entities();
var namenQuery = from n in ctx.Names select new { n.UserId, n.Name };
foreach (var val in namenQuery) { Console.WriteLine("{0}, {1}", val.UserId, val.Name); } |
danielf hat folgendes geschrieben : |
Die Zuordnung musst du glaub so oder so in der DB machen mit PK u. FK.
|
Für eine Query brauche ich die nicht. Eine Abfrage von Daten aus beiden Tabellen sieht dann so aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| SimpleDB01Entities ctx = new SimpleDB01Entities();
var namenQuery = from n in ctx.Names join p in ctx.Prenames on n.UserId equals p.UserId select new { n.UserId, n.Name, p.Prename };
foreach (var val in namenQuery) { Console.WriteLine("{0}, {1}, {2}", val.UserId, val.Name, val.Prename); } |
Vielen Dank für die Hilfe.
Gruss,
Gunther
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!