2016-08-02 9 views
1

Ich habe zwei Tabellen, die eine von ihnen zu anderen beziehen. Die erste TabelleZwei Primarykeys auf derselben Tabelle und Fremdschlüssel

public class Text 
    { 
    [Key] 
    [Column(Order = 1)] 
    [Required] 
    [MinLength(7)] 
    [MaxLength(7)] 
    public string Fieldname { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [Required] 
    public virtual Language Language { get; set; } 

    [MaxLength(50)] 
    [MinLength(1)] 
    [Required] 
    public string Description { get; set; } 
    } 

und die zweite Tabelle:

public class Language 
    { 
    [Key] 
    [Required] 
    [MaxLength(2), MinLength(2)] 
    public string Code { get; set; } 
    [Required] 
    public string Country { get; set; } 
    } 

Die Daten Samen sieht wie folgt:

context.Language.AddOrUpdate(
     new Language() {Code = "DE", Country = "German"}, 
     new Language() {Code = "EN", Country = "English"}); 

context.Text.AddOrUpdate(
     new Text { Fieldname = "TEXT001", Description = "Server", Language = context.Language.First(e => e.Code == "EN") }, 
     new Text { Fieldname = "TEXT001", Description = "Server", Language = context.Language.First(e => e.Code == "DE") } 
    ); 

ich die db aktualisieren und bekam folgende Fehlermeldung:

System.Data.Entity.Core .UpdateException: Beim Aktualisieren der Einträge ist ein Fehler aufgetreten. Weitere Informationen finden Sie in der inneren Ausnahme. ---> System.Data.SqlClient.SqlException: Verletzung der PRIMARY KEY-Einschränkung 'PK_dbo.Texts'. Kann doppelten Schlüssel in Objekt 'Dbo.Texts' nicht einfügen. Der doppelte Schlüsselwert ist (TEXT001).

Was ist los?

+2

Ja, aber in Kombination mit den Feldern 'Feldname' und' Sprache'. Bitte schau dir die Seeddaten an, dann solltest du was ich meine. –

+0

@zero_coding - Nicht sicher, aber ich denke, Sie sollten angeben, dass der 'Language'' Schlüssel' ein Fremdschlüssel ist - '[Key, ForeignKey (" Language "), Spalte (Order = 2)]' –

+0

setzt komplexe Eigenschaft ' Sprache als Schlüssel gültig? –

Antwort

1

@IvanStoev Antwort richtig ist. Aber ich möchte eine andere Option zeigen. Ich empfehle Ihnen, Ihre Klassen mithilfe der Fluent-API zuzuordnen. Glauben Sie mir, auf diese Weise bleiben Ihre Modelle viel sauberer und Abbildungen sind leicht zu verstehen.

Text Modell und Mapping für sie:

public class Text 
{ 
    public string FieldName { get; set; } 
    public string LanguageCode { getl set; } // Add this foriegn key property 
    public string Description { get; set; } 

    // Navigation properties 
    public virtual Language Language { get; set; } 
} 

internal class TextMap 
    : EntityTypeConfiguration<Text> 
{ 
    public TextMap() 
    { 
     // Primary key 
     this.HasKey(m => new { m.FieldName, m.LanguageCode }); 

     this.Property(m => m.FieldName) 
       .HasMaxLength(7) 
       .IsFixedLength(); 

     this.Property(m => m.LanguageCode) 
       .HasMaxLength(2) 
       .IsFixedLength(); 

     // Properties 
     this.Property(m => m.Description) 
      .IsRequired() 
      .HasMaxLength(50);      

     // Relationship mappings 
     this.HasRequired(m => m.Language) 
      .WithMany() 
      .HasForeignKey(m => m.LanguageCode) 
      .WillCascadeOnDelete(false); 
    } 
} 

Sprache Modell und Mapping für sie:

public class Language 
{ 
    public string Code { get; set; } 
    public string Country { get; set; } 
} 

internal class LanguageMap 
    : EntityTypeConfiguration<Language> 
{ 
    public LanguageMap() 
    { 
     // Primary key 
     this.HasKey(m => m.Code); 

     this.Property(m => m.Code) 
       .HasMaxLength(2) 
       .IsFixedLength(); 

     // Proeprties 
     this.Property(m => m.Country) 
      .IsRequired(); 
    } 
} 

Dann sollten Sie OnModelCreating Methode von DbContext außer Kraft setzen und fügen Sie Ihre Zuordnungen wie:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Configurations.Add(new TextMap()); 
    modelBuilder.Configurations.Add(new LanguageMap()); 
} 
+0

Also muss ich in der Navigationseigenschaft '[Key]' nicht mehr setzen? –

+0

Sie haben einen Primärschlüssel bei Navigation proeprty, aber Sie verwenden keine der Attribute, wenn Sie die Fluent-API verwenden. @zero_coding –

+0

aha ok. Ich werde es versuchen und Sie wissen lassen. –

1

Ich glaube nicht, dass Sie Teil der PK mit Navigationseigenschaft definieren können, so einfach EF Ihre Column und Key Attribute auf Language Eigenschaft ignoriert, endet mit PK nur Fieldname zu sein.

Sie müssen das FK Feld explizit wie folgt umfassen:

public class Text 
{ 
    [Key] 
    [Column(Order = 1)] 
    [Required] 
    [MinLength(7)] 
    [MaxLength(7)] 
    public string Fieldname { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [Required] 
    [MaxLength(2), MinLength(2)] 
    public string LanguageCode { get; set; } 

    [ForeignKey("LanguageCode")] 
    public virtual Language Language { get; set; } 

    [MaxLength(50)] 
    [MinLength(1)] 
    [Required] 
    public string Description { get; set; } 
} 
Verwandte Themen