2013-09-22 5 views
11

Wie würde ich die folgende Beziehung in Entity Framework 5 abbilden?Entity Framework 5 Code Erste selbstverweisende Beziehung

public class Item { 
    public int Id { get; set; } 
    public int? ParentItemId { get; set; } 
    public string Value { get; set; } 

    public Item ParentItem { get; set; } 
    public List<Item> ChildItems { get; set; } 
} 

Ich habe dies versucht:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Entity<Item>() 
       .HasOptional(i => i.ParentItem) 
       .WithMany(i => i.ChildItems) 
       .HasForeignKey(i => i.ParentItemId); 
} 

und diese:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Entity<Item>() 
       .HasMany(i => i.ChildItems) 
       .WithOptional(i => i.ParentItem) 
       .HasForeignKey(i => i.ParentItemId); 
} 

die beide Ergebnis in diesem Fehler:

Die Typen aller Eigenschaften in den abhängigen Die Rolle einer referenziellen Integritätsregel muss mit den entsprechenden Eigenschaftstypen in Pri identisch sein wichtige Rolle.

Wenn ich mit Datenbank-first-Mapping zu starten, hier ist das, was die erzeugte Einheit wie folgt aussieht:

public partial class Item 
{ 
    public Item() 
    { 
     this.ChildItems = new HashSet<Item>(); 
    } 

    public int Id { get; set; } 
    public Nullable<int> ParentItemId { get; set; } 
    public string Value { get; set; } 

    public virtual ICollection<Item> ChildItems { get; set; } 
    public virtual Item ParentItem { get; set; } 
} 

Ich weiß, das wird funktionieren, wenn ich mit db-zum ersten Mal starten, ich muss nur wissen, wie man Definieren Sie die Beziehung zuerst in Code.

+0

Ist 'Id' die Schlüsseleigenschaft? Oder haben Sie eine Schlüsselzuordnung (mit Fluent API?) Zu einer anderen Eigenschaft, zum Beispiel zu "Value"? – Slauma

+0

Id ist die Primärschlüsseleigenschaft von Item. – user326502

+0

"* Typen aller Eigenschaften in der abhängigen Rolle *" bedeutet die Typen der FK-Eigenschaft, die 'ParentItemId' ist und den Typ' int? 'Hat. "* entsprechende Eigenschaftstypen in der Principal Role *" bedeutet die Typen der PK-Eigenschaft, die "Id" ist und den Typ "int" hat. Sie sind die gleichen (Nullbarkeit ist egal). Die Ausnahme sagt jedoch, sie sind nicht. Die Ausnahme würde auftreten, wenn Sie zum Beispiel einen 'langen' (oder einen anderen Typ) für den PK und einen 'int? 'Für den FK hätten. Ziemlich merkwürdig ... – Slauma

Antwort

2

Die Ausnahme sind die folgenden:

  • Typen aller Eigenschaften in den abhängigen Rollen“ sind die Arten der FK Eigenschaft, die ParentItemId und hat int? in Ihrem Modell Typ
  • "Die entsprechenden Eigenschaftstypen in der Principal Role "sind die Typen der PK-Eigenschaft Id und haben in Ihrem Modell int den Typ

Sie sind die gleichen (nullbarkeit ist egal). Die Ausnahme sagt jedoch, sie sind nicht.

Die Ausnahme würde normalerweise nur auftreten, wenn die Typen nicht übereinstimmen, z. B. wenn Sie einen long (oder einen anderen Typ) für den PK und einen int? für den FK hatten.

0

Versuchen Sie es mit dem mapKey-Verfahren, anstatt HasForeignKey zu verwenden. Wie

modelBuilder.Entity<Course>() 
    .HasRequired(c => c.Department) 
    .WithMany(t => t.Courses) 
    .Map(m => m.MapKey("ChangedDepartmentID")); 
+0

Danke, dass Sie sich die Zeit genommen haben zu antworten. Wenn ich es auf diese Weise versuche, erhalte ich den folgenden Fehler: Jeder Eigenschaftsname in einem Typ muss eindeutig sein. Der Eigenschaftsname 'ParentItemId' wurde bereits definiert. – user326502

+0

Fügen Sie der ParentItemId-Eigenschaft direkt vor der obigen Viele-zu-Eins-Zuordnung eine Ignorierung hinzu. modelBuilder.Entity () .Ignore (it => it.ParentItemId); –

7

In Code zuerst Ihre Entity-Klasse wie folgt ändern:

public class Item 
    { 
     public Item() 
     { 
      this.ChildItems = new HashSet<Item>(); 
     } 

     public int Id { get; set; } 
     public Nullable<int> ParentItemId { get; set; } 
     public string Value { get; set; } 

     public virtual Item ParentItem { get; set; } 
     public virtual ICollection<Item> ChildItems { get; set; } 
    } 

den folgenden Code in Ihrer Kontextdatei schreiben:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Item>() 
        .HasOptional(i => i.ParentItem) 
        .WithMany(i => i.ChildItems) 
        .HasForeignKey(i => i.ParentItemId); 
    } 

dieses Denken funktionieren soll.

+0

Danke, dass du dir die Zeit genommen hast zu antworten. Wenn ich es auf diese Weise versuche, bekomme ich immer noch denselben Fehler: Die Typen aller Eigenschaften in der abhängigen Rolle einer referenziellen Integritätsbedingung müssen mit den entsprechenden Eigenschaftstypen in der Hauptrollenfunktion übereinstimmen. – user326502

3

Warum nicht versuchen:

public class Item 
    { 
     public Item() 
     { 
      ChildItems = new HashSet<Item>(); 
     } 

     public int Id { get; set; } 
     public int? ParentItemId { get; set; } 
     public string Value { get; set; } 

     public virtual Item ParentItem { get; set; } 
     public virtual ICollection<Item> ChildItems { get; set; } 
    } 

Und in Ihrer DataContex Klasse:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Item>() 
        .HasOptional(i => i.ParentItem) 
        .WithMany() 
        .HasForeignKey(i => i.ParentItemId); 
    } 

Hoffnung diese Arbeit.

Auch gibt es einen guten Artikel hier: Wie ein Selbstverweisende Entität in-Code Zuerst konfigurieren http://blogs.microsoft.co.il/gilf/2011/06/03/how-to-configure-a-self-referencing-entity-in-code-first/