Entity Framework Code First - 循环关系的奇怪行为
Entity Framework Code First - strange behaviour with circular relationship
我很难理解 Code First 如何基于模型建立关系。这是模型:
public class Person
{
[Key]
public string PersonName { get; set; }
[Required]
public virtual Nation NationOfBirth { get; set; }
[Required]
public virtual Nation CurrentNationOfResidence { get; set; }
}
public class Nation
{
[Key]
public string NationName { get; set; }
public virtual Person CurrentSecondInCommand { get; set; }
}
起初我在创建数据库时遇到错误,我通过添加几个 modelBuilder 命令解决了这个问题:
modelBuilder.Entity<Person>()
.HasRequired(p => p.NationOfBirth)
.WithRequiredDependent()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Person>()
.HasRequired(p => p.CurrentNationOfResidence)
.WithRequiredDependent()
.WillCascadeOnDelete(false);
我还补充了:
modelBuilder.Entity<Nation>()
.HasOptional(n => n.CurrentSecondInCommand)
.WithOptionalDependent()
.WillCascadeOnDelete(false);
现在,当我尝试使用以下代码填充我的数据库时:
var america = new Nation { NationName = "America" };
context.Nations.Add(america);
var bush = new Person { PersonName = "Bush", CurrentNationOfResidence = america, NationOfBirth = america };
var obama = new Person { PersonName = "Obama", CurrentNationOfResidence = america, NationOfBirth = america };
var biden = new Person { PersonName = "Biden", CurrentNationOfResidence = america, NationOfBirth = america };
context.People.Add(bush);
context.People.Add(obama);
context.People.Add(biden);
context.SaveChanges();
在添加 'bush' 的位置,CurrentNationOfResidence 和 NationOfBirth 属性对他来说都不为空,并且设置为 'america' 对象。但是一旦添加 'obama','bush' 上的 CurrentNationOfResidence 和 NationOfBirth 属性都会变为空。添加 'biden' 后 'obama' 也会发生同样的情况。
如果我检查由此生成的数据库,我看不到在 People table 上创建的任何外键列,但我希望 Code First 自动生成 2 个外键Person 上的两个 Nation 字段(这就是我认为我的前两个 modelBuilder 命令会做的 - 来自 "WithRequiredDepedent" 的描述)。更奇怪的是,数据库中添加了一个名为 "America" 的人,以及一个也称为 America 的国家。
如果有人能提供有关我的模型的一般建议,我将不胜感激。我意识到我在这里有一个循环关系,但我认为这没关系,因为国家不需要有 CurrentSecondInCommand。我意识到它有点复杂(或者也许用令人费解的词更好)但我认为它是有道理的:
- 一个人必须有一个(民族)NationOfBirth。
- 一个人必须有一个(国家)CurrentNationOfResidence。
- 一个国家可以选择拥有一个(个人)CurrentSecondInCommand。
非常欢迎任何建议,谢谢。
国家 class 中的虚拟 属性 必须是 ICollection<Person> CurrentSecondInCommand
,这样你在数据库中就会有 "many persons in one nation" 关系将是 "one to many" 而不是"one to one"
Person与Nation的两种关系不是一对一的,而是多对一的:
- 一个人必须有一个(民族)出生国。但是一个国家有很多人在那里出生
- 一个人必须有一个(国家)CurrentNationOfResidence。但是一个国家有很多居民
所以你的配置应该是:
modelBuilder.Entity<Person>()
.HasRequired(p => p.NationOfBirth)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Person>()
.HasRequired(p => p.CurrentNationOfResidence)
.WithMany()
.WillCascadeOnDelete(false);
我很难理解 Code First 如何基于模型建立关系。这是模型:
public class Person
{
[Key]
public string PersonName { get; set; }
[Required]
public virtual Nation NationOfBirth { get; set; }
[Required]
public virtual Nation CurrentNationOfResidence { get; set; }
}
public class Nation
{
[Key]
public string NationName { get; set; }
public virtual Person CurrentSecondInCommand { get; set; }
}
起初我在创建数据库时遇到错误,我通过添加几个 modelBuilder 命令解决了这个问题:
modelBuilder.Entity<Person>()
.HasRequired(p => p.NationOfBirth)
.WithRequiredDependent()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Person>()
.HasRequired(p => p.CurrentNationOfResidence)
.WithRequiredDependent()
.WillCascadeOnDelete(false);
我还补充了:
modelBuilder.Entity<Nation>()
.HasOptional(n => n.CurrentSecondInCommand)
.WithOptionalDependent()
.WillCascadeOnDelete(false);
现在,当我尝试使用以下代码填充我的数据库时:
var america = new Nation { NationName = "America" };
context.Nations.Add(america);
var bush = new Person { PersonName = "Bush", CurrentNationOfResidence = america, NationOfBirth = america };
var obama = new Person { PersonName = "Obama", CurrentNationOfResidence = america, NationOfBirth = america };
var biden = new Person { PersonName = "Biden", CurrentNationOfResidence = america, NationOfBirth = america };
context.People.Add(bush);
context.People.Add(obama);
context.People.Add(biden);
context.SaveChanges();
在添加 'bush' 的位置,CurrentNationOfResidence 和 NationOfBirth 属性对他来说都不为空,并且设置为 'america' 对象。但是一旦添加 'obama','bush' 上的 CurrentNationOfResidence 和 NationOfBirth 属性都会变为空。添加 'biden' 后 'obama' 也会发生同样的情况。
如果我检查由此生成的数据库,我看不到在 People table 上创建的任何外键列,但我希望 Code First 自动生成 2 个外键Person 上的两个 Nation 字段(这就是我认为我的前两个 modelBuilder 命令会做的 - 来自 "WithRequiredDepedent" 的描述)。更奇怪的是,数据库中添加了一个名为 "America" 的人,以及一个也称为 America 的国家。
如果有人能提供有关我的模型的一般建议,我将不胜感激。我意识到我在这里有一个循环关系,但我认为这没关系,因为国家不需要有 CurrentSecondInCommand。我意识到它有点复杂(或者也许用令人费解的词更好)但我认为它是有道理的:
- 一个人必须有一个(民族)NationOfBirth。
- 一个人必须有一个(国家)CurrentNationOfResidence。
- 一个国家可以选择拥有一个(个人)CurrentSecondInCommand。
非常欢迎任何建议,谢谢。
国家 class 中的虚拟 属性 必须是 ICollection<Person> CurrentSecondInCommand
,这样你在数据库中就会有 "many persons in one nation" 关系将是 "one to many" 而不是"one to one"
Person与Nation的两种关系不是一对一的,而是多对一的:
- 一个人必须有一个(民族)出生国。但是一个国家有很多人在那里出生
- 一个人必须有一个(国家)CurrentNationOfResidence。但是一个国家有很多居民
所以你的配置应该是:
modelBuilder.Entity<Person>()
.HasRequired(p => p.NationOfBirth)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Person>()
.HasRequired(p => p.CurrentNationOfResidence)
.WithMany()
.WillCascadeOnDelete(false);