Entity Framework 4 – Ein neuer Workaround für 1 : 1 – Mapping
Mit EF 4 geht schon einiges viel leichter von der Hand, aber ein paar Dinge funktionieren auch nicht immer, wie man es sich in der Theorie vorstellt bzw. von der ersten Version her gewohnt ist.
Nun wollte ich ein 1 : 1 Mapping im Designer definieren, bei dem der Fremdschlüssel nicht der Primary-Key ist. Die Fehlermeldung, die mich hier begrüsste, lautet so:
Error 113: Multiplicity is not valid in Role 'PersonDetail' in relationship 'FK_PersonDetail_Person'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be *.
Wer auf der grünen Wiese anfängt, dem kann dieses Problem egal sein, da die Datenbankstruktur nicht vorgegeben ist und die Tabellen entsprechend angelegt werden können.
Bei bestehenden Datenbanken kommt es noch häufig vor, das es einen Primärschlüssel auf der Tabelle gibt und einen Fremdschlüssel mit einem Unique Constraint, der die Beziehung abbildet.
Wenn nun das Modell erstellt und die globale Eigenschaft „Include foreign key columns in the model“ abgewählt wird, dann kann die Beziehung von 1 : * in 1 : 1 abgeändert werden, die Validierung ist erfolgreich und die Funktionalität ist gegeben. Ist diese Checkbox aktiviert, dann funktioniert die Änderung der Beziehung in 1 : 1 nicht mehr.
Der Grund für dieses Verhalten liegt in den Anpassungen, die an der Version 4.0 vorgenommen worden sind. Wenn die Fremdschlüssel nicht mit in das Modell einbezogen werden, dann werden die Beziehungen über die Navigations-Eigenschaften abgebildet. Dies ist der Standard in EF 3.5 und funktioniert auch in EF 4.0 ohne die Fremdschlüssel-Eigenschaften.
Wenn die Fremdschlüssel-Eigenschaften im Modell abgebildet werden, dann wird eine Beziehung über die skalaren Eigenschaften hergestellt. Durch diese Änderung wird bspw. das unidirektionale Mapping möglich.
Kritiker werden aber hier erneut den Daumen drauflegen und mit der Persistence Ignorance argumentieren und Gerüchten zufolge wird bereits an einer Lösung gearbeitet. ;-)
Bis dahin kann mit ein wenig Codierungsaufwand, die 1 : 1 – Beziehung simuliert werden, da dieser aus meiner Sicht den geringsten Realisierungsaufwand darstellt. Es müssen nur die Include-Anweisungen mit dieser Entität im Auge behalten werden, damit der Workaround später einfacher entfernt werden kann, falls das Verhalten wie in der Vorversion realisiert werden sollte.
Notwendige Schritte für den Workaround:
- Hinzufügen der Entitäten auf den Modelldesigner
- Den Getter und Setter für die PersonDetails – Eigenschaft auf private setzen (nach aussen verbergen)
- Partial-Klasse hinzufügen, die eine Eigenschaft bereitstellt, die nur ein PersonDetail zurückgibt
Der Code der Partial-Klasse sieht dann bspw. so aus:
C# (Person.WorkaroundOneToOne.cs)
namespace OneToOneEF4
{
using System;
using System.Linq;
public partial class Person
{
public PersonDetail PersonDetail
{
set
{
if (this.PersonDetails.Count > 0)
{
this.PersonDetails.RemoveAt(0);
}
this.PersonDetails.Add(value);
}
get
{
return this.PersonDetails.FirstOrDefault();
}
}
}
}
Nachteilig ist, dass in diesem Fall Model und Code nicht synchron sind und diese Eigenschaft in Linq-Abfragen nicht angesprochen werden kann.
- 0 Kommentar(e)





Mein Kommentar