| 

.NET C# Java Javascript Exception

5
Hallo, ich möchte eine Klasse Produkt abbilden welche zwei Mengeneinheiten unterstützen soll. Der Faktor gibt an, wie oft die Mengeneinheit 1 in der Mengeneinheit 2 enthalten ist (z.B. 1 Packung enthält 12 Stück - Faktor = 12)
public class Product
{
public int ProductId { get; set; }
public string Description { get; set; }
public virtual int Me1 { get; set; }
public virtual QuantityUnit QuantityUnit1 { get; set; }

public virtual int? Me2 { get; set; }
public virtual QuantityUnit QuantityUnit2 { get; set; }

public virtual float? Factor2 { get; set; }
}

Dazu gib es die Classe QuantityUnit
public class QuantityUnit
{
[Key]
public int UnitId { get; set; }
public string Description { get; set; }

public virtual ICollection<Product> Products { get; set; }
}

Werden die Relationen in der Klasse Product mit dem Attribut [ForeignKey()] abgebildet funktioniert es, allerding ist CascadeOnDelete dann true, so dass beim Löschen einer Mengeneinheit alle Artikel, die die entsprechende Mengeneinheit verwenden mitgelöscht werden.
Daher habe ich die Relationen in der OnModelCreating - Methode meine DbContext-Klasse wie folgt konfiguriert:
modelBuilder.Entity<Product>()
.HasRequired(p => p.QuantityUnit1)
.WithMany(q => q.Products)
.HasForeignKey(k => k.Me1)
.WillCascadeOnDelete(false);

modelBuilder.Entity<Product>()
.HasRequired(p => p.QuantityUnit2)
.WithMany(q => q.Products)
.HasForeignKey(k => k.Me2)
.WillCascadeOnDelete(false);

Wenn ich nur eine Relation definiere funktioniert es, wenn ich jedoch beide Relationen definiere, erhalte ich den Fehler:
"Das angegebene Schema ist ungültig. Fehler: \r\n(22,6) : Fehler 0040: Typ Product_QuantityUnit1 ist nicht in Namespace Mvc3Application.Models definiert (Alias=Self)."


Hat jemand eine Idee dazu?
21.06.2011
Torsten Menze 113 1 5
Auf die Beantwortung dieser Frage war ein Kopfgeld in Höhe von 100 Reputationspunkten ausgesetzt. Das Kopfgeld wurde bereits vergeben.
2 Antworten
1
Update:
Ich glaube, die Lösung steht hier bei stackoverflow. Die Rückwärtsnavigation von QuantityUnit zu Product (wofür brauchst Du die eigentlich in diesem Szenario?) kann nicht über den selben Member gehen. D.h. das EF stört sich daran, dass bei beiden Relationen die Zeile ".WithMany(q => q.Products)" auftaucht. Irgendwie auch gar nicht so unlogisch, denn rein vom Objektmodell her könntest Du QuantityUnit1 und QuantityUnit2 mit dem gleichen Wert belegen, und wie oft soll das Product dann für diese QuantityUnit in Products auftauchen?

Voriger Lösungsversuch:
Hm, erstmal fällt mir auf, dass Dein Beispiel-Code zum modelBuilder so aussieht, als ob die Relation zu QuantityUnit2 Pflicht wäre, die Nullable-Typen in der Product-Klasse hingegen lassen eher auf eine optionale Relation schließen.

Ansonsten: wenn Du nur eine der beiden Relationen über den ModelBuilder definierst, kommt dann zumindest das selbe DB-Schema heraus wie bei der Variante mit dem ForeignKey-Attribute (bis auf die fehlende Relation natürlich)?

Und hast Du Dir mal diesen Forums-Thread angesehen? Vermutlich nicht ganz das selbe Problem, aber zumindest hatte dort jemand (der letzte Poster, nicht der Fragesteller) anscheinend die gleiche Fehlermeldung wie Du. Ist aber vielleicht schon mal ein kleiner Schritt zu einer Lösung.

Andere Fehlermeldungen gibt es keine, oder?
19.07.2011
Matthias Hlawatsch 13,2k 4 9
1
Der Hintergrund ist, dass jedem Produkt drei QuantityUnits zugeordnet werden sollen, die Erste Pflicht, die Anderen optional. Der Code oben ist also falsch. Der Gedanke für die Verknüpfungen im Code oben war, für jede QuantityUnit über
Product.QuantityUnit.Description
direkt auf die Beschreibung zugreifen zu können. Ich habe den Code jetzt wie folgt geändert:
modelBuilder.Entity<Product>()
.HasRequired(p => p.QuantityUnit)
.WithMany(q => q.Products)
.HasForeignKey(k => k.Me1)
.WillCascadeOnDelete(false);

modelBuilder.Entity<Product>()
.HasOptional(p => p.QuantityUnit)
.WithMany(q => q.Products)
.HasForeignKey(k => k.Me2)
.WillCascadeOnDelete(false);

modelBuilder.Entity<Product>()
.HasOptional(p => p.QuantityUnit)
.WithMany(q => q.Products)
.HasForeignKey(k => k.Me3)
.WillCascadeOnDelete(false);


so funktioniert es. Man kann leider nicht wie oben einfach auf die Beschreibung zugreifen, sondern muss sie separat über die jeweilige Id abfragen.
31.07.2011
Torsten Menze 113 1 5

Stelle deine .net-Frage jetzt!