我是EF和流畅API的新手。我的DBA决定他想在公民身份表中绘制一个具有Is_Primary标志的人的“主要”公民身份。所以我们的DB看起来像这样:
**Person Table**
Person_Id int identity (PK)
First_Name nvarchar(30)
...
**Citizenship_Table**
Citizenship_Person_Id int identity (PK)
Person_Id int
Country_Code char(2)
Is_Primary byte
...
**Country_Table**
Country_Code char(2) (PK)
Country_Name varchar(30)
...
我真的不想在我的域模型中使用Is_Primary标志。相反,我希望我的域看起来像这样:
public class Person
{
public int Id {get; set;}
...
public virtual ICollection<Country> Citizenships {get; set;}
public Country PrimaryCitizenship {get; set;}
}
public class Country
{
public int Code {get; set;}
public string Name {get; set;}
}
有没有办法映射这种情况?
答案 0 :(得分:0)
无法将域模型提案映射到给定的表结构。在我看来,从域名的角度来看,将Is_Primary
标志引入公民身份表(基本上是Person
和Country
之间的联接表)也是错误的。
该域名表示一个人可以拥有一个主要公民身份(或许没有),但绝不会许多。表结构中没有正确表达:Is_Primary
列可以为给定的人设置多个国家/地区。改变一个人的主要公民身份也很困难,因为如果有另一个国家标记为主要国家,则必须搜索属于该人的公民身份表中的所有条目,然后在为新国家设置标志之前重置此标志
这在模型中正确表达,这意味着Person
应该具有Country
表的外键(必需或可选)。更改主要公民身份只需要将此FK设置为其他值。在此模型中不可能出现重复的主标记。
如果您将表结构相应更改为以下...
**Person Table**
Person_Id int identity (PK)
First_Name nvarchar(30)
PrimaryCountry_Code char(2) (FK to Country table)
...
**Citizenship_Table**
Person_Id int (PK)
Country_Code char(2) (PK)
**Country_Table**
Country_Code char(2) (PK)
Country_Name varchar(30)
...
...可以映射到您的模型:
modelBuilder.Entity<Person>()
.Property(p => p.Id)
.HasColumnName("Person_Id");
modelBuilder.Entity<Person>()
.Property(p => p.Name)
.HasColumnName("First_Name")
.HasMaxLength(30);
modelBuilder.Entity<Person>()
.HasMany(p => p.Citizenships)
.WithMany()
.Map(a => {
a.MapLeftKey("Person_Id");
a.MapRightKey("Country_Code");
a.ToTable("Citizenship");
});
modelBuilder.Entity<Person>()
.HasOptional(p => p.PrimaryCitizenship) // or .HasRequired(...)
.WithMany()
.Map(a => a.MapKey("PrimaryCountry_Code"))
.WillCascadeOnDelete(false);
modelBuilder.Entity<Country>()
.HasKey(c => c.Code)
.Property(c => c.Code)
.HasColumnName("Country_Code")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
.HasMaxLength(2)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<Country>()
.Property(c => c.Name)
.HasColumnName("Country_Name")
.HasMaxLength(30)
.IsUnicode(false);
不是解决问题的方法,而是与DBA讨论的一些食物。