使用Fluent语法定义从人到国家而不是从国家到人的导航

时间:2014-11-19 10:28:26

标签: entity-framework ef-code-first entity-framework-6 fluent-entity-framework

我在约定定义的PersonCountry之间存在以下关系。这非常有效。

public class Person
{
    public long PersonId {get; set;}
    public string Name {get; set;}

    public long CountryId {get; set;}
    public virtual Country Country {get; set;}
}

public class Country
{
    public long CountryId {get; set;}
    public string Name {get; set;}
}

我现在希望将属性Country的名称更改为其他内容。据我所知,这意味着这种关系不再符合惯例。所以我希望使用流畅的语法来定义它。

我找到了this引用,但我不清楚我应该如何处理这个确切的场景,因为在他们的示例中,关系的两个方面都包含外键或集合。

有一节"配置与一个导航属性的关系"这让我觉得应该是这样的:

modelBuilder.Entity<Patient>() 
    .HasRequired(t => t.Country) 
    .WithRequiredPrincipal();

但是,每当存储国家/地区时,都会导致以下异常

{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_dbo.Countries_dbo.Patients_CountryId\". The conflict occurred in database \"TESTS_ffbe7a6e73a747ce8cda71f963bb20b7\", table \"dbo.Patients\", column 'PatientId'.\r\nThe statement has been terminated."}

所以现在我的问题是: - 我如何根据惯例定义上述&#39;使用流畅的语法关系? - 使用流利语法时是否仍需要CountryId属性?

1 个答案:

答案 0 :(得分:1)

在您的示例代码中,您表达了这一点:

  • Entity<Patient>().HasRequired(t => t.Country):每位患者必须有相关的国家/地区
  • .WithRequiredPrincipal():每个国家/地区都必须有相关患者

我想你不需要每个国家都有一个或多个相关患者。所以,这样做:

  modelBuilder.Entity<Person>()
              .HasRequired(p => p.Country)
              .WithMany();

这意味着每个人必须拥有一个国家,每个国家都可以拥有许多相关人员。并且您没有在不同国家/地区指定任何协议。

要理解这种流畅的API关系,要考虑到第一个函数(即HasRequired)是从第一个实体到第二个实体的关系。然后,第二个函数(即WithXXX)是从第二个实体到第一个实体的关系。

感谢Fluent API,很容易表达任何形式的关系,而不会出错。除了有或没有参数的重载允许您指定导航属性,或者如果它们不存在则省略它们。例如,如果您需要使用Persons属性从国家/地区导航回到人员,则看起来像这样:

  WithMany(c => c.Persons)