2013-09-22 17 views
11

Come mappare la seguente relazione in Entity Framework 5?Entity Framework 5 Codice prima relazione autoreferenziale

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; } 
} 

Ho provato questo:

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

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

e questo:

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

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

che sia risultato in questo errore:

I tipi di tutte le proprietà del dipendente Il ruolo di un vincolo referenziale deve essere lo stesso dei tipi di proprietà corrispondenti nel Pri ruolo centrale.

Se inizio con la mappatura di database-prima, qui è quello che l'entità generato assomiglia:

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; } 
} 

So che questo funzionerà se comincio con db-prima, ho solo bisogno di sapere come definire la relazione in code-first.

+0

è 'Id' la proprietà chiave? O hai una mappatura delle chiavi (con Fluent API?) Su un'altra proprietà, ad esempio su 'Value'? – Slauma

+0

Id è la proprietà chiave primaria dell'articolo. – user326502

+0

"* tipi di tutte le proprietà nel ruolo dipendente *" indica i tipi della proprietà FK che è 'ParentItemId' e ha tipo' int? '. "* corrispondenti tipi di proprietà nel ruolo principale *" indica i tipi della proprietà PK che è 'Id' e ha tipo' int'. Sono uguali (il nullability non ha importanza). Tuttavia, l'eccezione dice che non lo sono. L'eccezione si verificherebbe se tu avessi per esempio un 'long' (o qualsiasi altro tipo) per il PK e un' int? 'Per l'FK. Piuttosto strano ... – Slauma

risposta

2

L'eccezione si intendono i seguenti:

  • "tipi di tutte le proprietà nel ruolo Dipendente" sono i tipi di proprietà FK che è ParentItemId e ha digitare int? nel modello
  • "corrispondenti tipi di proprietà nel ruolo principale "sono i tipi della proprietà PK che è Id e ha tipo nel modello

Sono uguali (il nullability non ha importanza). Tuttavia, l'eccezione dice che non lo sono.

L'eccezione normalmente si sarebbe verificato solo se i tipi non corrispondono, ad esempio, se si ha un long (o qualsiasi altro tipo) per il PK e un int? per l'FK.

0

Provare ad usare mapKey per farlo piuttosto che usare HasForeignKey. Come

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

Grazie per aver trovato il tempo di rispondere. Quando provo in questo modo, ottengo il seguente errore: Ogni nome di proprietà in un tipo deve essere univoco. Il nome della proprietà "ParentItemId" era già definito. – user326502

+0

Aggiungere un ignorato alla proprietà ParentItemId subito prima del numero di mapping sopra molti a uno .. modelBuilder.Entity () .Ignore (it => it.ParentItemId); –

7

Nel codice prima cambiare la classe entità in questo modo:

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; } 
    } 

scrivere il seguente codice al tuo file di contesto:

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

che questo dovrebbe funzionare.

+0

Grazie per aver trovato il tempo di rispondere. Durante il tentativo in questo modo, viene visualizzato lo stesso errore: I tipi di tutte le proprietà nel ruolo dipendente di un vincolo referenziale devono essere uguali ai tipi di proprietà corrispondenti nel ruolo principale. – user326502

3

perché non provare questo:

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; } 
    } 

E nella classe DataContex:

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

Spero che questo lavoro.

Inoltre v'è un buon articolo qui: Come configurare un Sé Referencing Entità in codice prima http://blogs.microsoft.co.il/gilf/2011/06/03/how-to-configure-a-self-referencing-entity-in-code-first/

Problemi correlati