我有两张桌子,其中一张与其他桌子有关。 第一个表
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)。
有什么问题?
答案 0 :(得分:1)
我认为您不能使用导航属性定义PK的一部分,因此EF只会忽略Column
属性上的Key
和Language
属性,最终只会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; }
}
答案 1 :(得分: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());
}