2014-06-27 2 views
12

Ich benutze Entity Framework 6 mit einem Code-First-Ansatz, und ich möchte zwei Entitäten in die gleiche Tabelle. Was mache ich falsch?Entity Framework Tabellensplitting: nicht in der gleichen Typhierarchie/haben keine gültige eins zu eins Fremdschlüssel Beziehung

[Table("Review")] 
public class Review 
{ 
    public int Id { get; set; } 
    public PictureInfo PictureInfo { get; set; } 
    public int PictureInfoId { get; set; } 
} 

[Table("Review")] 
public class PictureInfo 
{ 
    [Key, ForeignKey("Review")] 
    public int ReviewId { get; set; } 
    public Review Review { get; set; } 
} 

Der Fehler erhalte ich: der ‚Review‘ Entitätstypen PictureInfo 'und kann nicht table ‚Review‘ teilen, weil sie nicht in der gleichen Art Hierarchie sind oder keine gültige 0.59 Fremdschlüsselbeziehung haben mit übereinstimmenden Primärschlüsseln zwischen ihnen.

Was mache ich falsch?

+0

Wie sollten diese Tabellen zusammenhängen? – sylwester

+0

Es ist eine Eins-zu-Eins-Beziehung. Jede Überprüfung hat eine PictureInfo, und jede PictureInfo gehört zu einer Review. Ich habe sie im Code getrennt, aber ich möchte, dass sie in dieselbe Tabelle gehen. – Andrew

Antwort

5

Scheint so, als ob das Problem darin bestünde, dass die Beziehung als Eins-zu-0..1 statt Eins-zu-Eins interpretiert wurde.

Der Fremdschlüssel int PictureInfoId am Ende der Überprüfung wurde nicht benötigt/ignoriert, so dass die Nicht-NULL-Fähigkeit das Review-Ende der Beziehung nicht erforderlich machte. Durch das Entfernen dieses unnötigen Schlüssels und das Hinzufügen des Attributs [Erforderlich] zur PictureInfo-Navigationseigenschaft wurde das Problem behoben.

Hier ist die korrigierte Review-Klasse.

+0

Danke, das Attribut [Erforderlich] hat das Problem für mich gelöst. – Jerry

5

Ich habe es geschafft, mit flüssigem api zu erreichen, was Sie wollten. Fluent api bietet viel umfangreichere Konfigurationsmöglichkeiten als Datenanmerkungen. Ich habe ein bisschen Ihre Entitätsklassen geändert:

public class Review 
{ 
    public int Id { get; set; } 
    public PictureInfo PictureInfo { get; set; } 
} 

PictureInfoId Eigenschaft nicht erforderlich ist, als Fremdschlüssel-Beziehung wird auf Primärschlüssel beiden Einheiten durchgeführt werden.

public class PictureInfo 
{ 
    public int Id { get; set; } 
    public Review Review { get; set; } 
} 

Da Kommentieren und PictureInfo auf denselben Tisch sie die gleiche Primärschlüsselspalte so für PictureInfo und Bewerten Sie diese Spalte den gleichen Namen haben sollte teilen müssen zugeordnet werden. Wenn Sie die Primärschlüsseleigenschaft "ReviewId" in PictureInfo beibehalten möchten, können Sie dies tun. Sie müssten dann jedoch ihren Namen "Id" zuordnen. Finaly die DbContext:

public class MyDbContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Review>().HasKey(e => e.Id); 
     modelBuilder.Entity<Review>() 
      .HasRequired(e => e.PictureInfo) 
      .WithRequiredDependent(e => e.Review); 
     modelBuilder.Entity<Review>().Map(m => m.ToTable("Review")); 
     modelBuilder.Entity<PictureInfo>().Map(m => m.ToTable("Review")); 
     modelBuilder.Entity<PictureInfo>().HasKey(e => e.Id); 

     base.OnModelCreating(modelBuilder); 
    } 

    public DbSet<Review> Reviews { get; set; } 
    public DbSet<PictureInfo> PictureInfos { get; set; } 
} 

OnModelCreating hält fließend api Mapping-Definition. Alles, was Sie tun müssen, ist, Primärschlüssel für beide Entitäten mit demselben Namen zu definieren, diese zwei Entitäten mit einer 1-1-Relation zu verknüpfen und sie dann der gleichen Tabelle zuzuordnen.

+0

Danke, Ihre Antwort hat mir geholfen, das Problem zu finden. Die PictureInfoId war in der Tat nutzlos, und ich brauchte ein [Erforderlich] -Attribut, um wirklich die Beziehung 1-zu-1 zu machen. Ich habe die datenanmerkungsbasierte Lösung veröffentlicht, da ich die Dinge nicht unnötig mit Fluent API mischen wollte. – Andrew

-1

Der Fehler wird verursacht, weil die Definition der Tabelle in der Direktive der Tabelle "PictureInfo" dupliziert wird. Sie müssen nur diese Anweisung bearbeiten.

[Table("Review")] public class Review { ... }

[Table("Review")] public class PictureInfo { ... }

für

[Table("Review")] public class Review { ... }

[Table("PictureInfo")] public class PictureInfo { ... }

+1

Das OP wollte dieselbe Tabelle verwenden, nicht zwei verschiedene Tabellen, wie Ihre Antwort zeigt. –

+0

+1 Danke für Ihre Antwort - halfen mir von meiner Idiotie zu retten. Das wird mir lehren, das Attribut zu kopieren/einfügen. – Behr

1

Die andere Möglichkeit, dieses Problem zu lösen, ist eine Ansicht mit nur den gewünschten Feldern zu erstellen. Dann ordnen Sie die Entität der Ansicht zu.

0

(Diese Tests und Fehler wurden für EF 6.1 geschrieben.3)

erster Versuch

[Table("Review")] 
public class Review 
{ 
    [Key] 
    public int Id { get; set; } 
    public PictureInfo PictureInfo { get; set; } 
} 

[Table("Review")] 
public class PictureInfo 
{ 
    [Key] 
    public int Id { get; set; } 
    public Review Review { get; set; } 
} 

Mit den oben genannten Entitäten erhielt ich diesen Fehler:

Unable to determine the principal end of an association between the types. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

Zweiten Versuch

[Table("Review")] 
public class Review 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    public PictureInfo PictureInfo { get; set; } 
} 

[Table("Review")] 
public class PictureInfo 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    public Review Review { get; set; } 
} 

The entity types 'Review' and 'PictureInfo' cannot share table 'Review' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.

dritter Versuch

[Table("Review")] 
public class Review 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required, ForeignKey("Id")] 
    public PictureInfo PictureInfo { get; set; } 
} 

[Table("Review")] 
public class PictureInfo 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required, ForeignKey("Id")] 
    public Review Review { get; set; } 
} 

Unable to determine the principal end of an association between the types. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

Arbeits-Code

[Table("Review")] 
public class Review 
{ 
    [Key, ForeignKey("PictureInfo")] 
    public int Id { get; set; } 

    public PictureInfo PictureInfo { get; set; } 
} 

[Table("Review")] 
public class PictureInfo 
{ 
    [Key, ForeignKey("Review")] 
    public int Id { get; set; } 

    public Review Review { get; set; } 
} 
0
using System.Linq; 
using System.Data.Entity; 
namespace Sample 
{ 

class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var context = new EmployeeDBContext()) 
      { 
       var result = context.Set<Employee>().Include(x => x.Department).ToArray(); 
      } 
     } 
    } 

public class EmployeeDBContext : DbContext 
    { 
     public EmployeeDBContext() : base("EmployeeDB") { } 

     public DbSet<Employee> Employee { get; set; } 
     public DbSet<Department> Department { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Department>().ToTable("Departments").HasKey(x => x.DepartmentId); 
      modelBuilder.Entity<Employee>().ToTable("Employees").HasKey(x => x.Id); 
      //ForeignKey mapping 
      modelBuilder.Entity<Employee>().HasRequired(x => x.Department).WithMany().HasForeignKey(x => x.DepartmentId); 
      base.OnModelCreating(modelBuilder); 
     } 
    } 

//Domain Entity 
    public class Employee 
    { 
     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public Department Department { get; set; } 
     public int DepartmentId { get; set; } 
    } 

    //Domain Entity 
    public class Department 
    { 
     public int DepartmentId { get; set; } 
     public string DepartmentName { get; set; } 
    } 
} 
+0

Ihr Code sieht anders aus als OP zur Verfügung gestellt. Bitte fügen Sie auch einige Details zu Ihrer Lösung hinzu. – mmushtaq

Verwandte Themen