同一个表和外键上的两个主键
我有两个表,其中一个与其他相关。 第一个表同一个表和外键上的两个主键
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)。
出了什么问题?
@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());
}
那么在导航属性中,我不必再设置'[Key]'了? –
在导航proeprty中有主键,但如果您使用Fluent API @zero_coding –
aha ok,则不使用任何属性。我生病了,让你知道。 –
我不认为你可以定义导航属性的PK的一部分,因此EF干脆忽略了Language
财产您Column
和Key
属性,以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; }
}
是的,但与字段'Fieldname'和'Language'结合使用。请查看种子数据,那么你应该明白我的意思。 –
@zero_coding - 不确定,但我认为你应该指定'语言''键'是一个外键 - '[Key,ForeignKey(“Language”),Column(Order = 2)]' –
设置复杂属性'语言是否有效? –