2016-08-02 99 views
1

我有两个表,其中一个与其他相关。 第一个表同一个表和外键上的两个主键

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

,第二个表:

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

种子数据看起来如下:

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

我更新数据库,并得到了以下错误消息:

System.Data.Entity.Core .UpdateException:更新条目时发生错误。详情请参阅内部例外。 ---> System.Data.SqlClient.SqlException:违反PRIMARY KEY约束'PK_dbo.Texts'。无法在对象'dbo.Texts'中插入重复键。重复的键值是(TEXT001)。

出了什么问题?

+2

是的,但与字段'Fieldname'和'Language'结合使用。请查看种子数据,那么你应该明白我的意思。 –

+0

@zero_coding - 不确定,但我认为你应该指定'语言''键'是一个外键 - '[Key,ForeignKey(“Language”),Column(Order = 2)]' –

+0

设置复杂属性'语言是否有效? –

回答

1

@IvanStoev答案是正确的。但我想展示另一种选择。我建议使用Fluent API来映射你的类。对我来说,这样,你的模型将会更加干净,映射也很容易理解。

文本模型和映射它:

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

语言模型和映射它:

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

那么你应该重写的DbContext的OnModelCreating方法并添加您的映射关系:

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

那么在导航属性中,我不必再设置'[Key]'了? –

+0

在导航proeprty中有主键,但如果您使用Fluent API @zero_coding –

+0

aha ok,则不使用任何属性。我生病了,让你知道。 –

1

我不认为你可以定义导航属性的PK的一部分,因此EF干脆忽略了Language财产您ColumnKey属性,以PK为刚Fieldname结束了。

你需要明确包括FK场这样的:

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; } 
} 
相关问题