【问题标题】:One to one relationship without reference property on one side一侧没有引用属性的一对一关系
【发布时间】:2018-05-22 10:49:43
【问题描述】:

我有以下构造;一个人的地址(ownsone,子实体)和一个国家的地址(hasone,一对一)

public class Person
{
     public Guid Id {get; set;}
     public string Name {get; set;}
     public Address Address {get; set;}
}

public class Address 
{
     public Guid Id {get; set;}
     public Guid CountryId {get; set;}
     public Country Country {get; set;}
}

public class Country
{
     public Guid Id {get; set;}
     public string CountryCode {get; set;}
}

public class EntityConfiguration<Person> where Person : class
{
     public void Configure(EntityBuilder<Person> builder)
     {
         builder.OwnsOne(p => p.Address, addressBuilder => 
         addressBuilder.HasOne(address => address.Country).WithOne();
     }
}

当我运行 Add-Migration 时,我会为每个拥有一个地址的实体获得一段代码。使用自动生成的密钥等。但我想用 HasForeignKey 明确指定关系。如何做到这一点?

【问题讨论】:

  • 我认为您需要做的第一件事是将外来对象声明为虚拟,例如,您的 person 类中的 Address 变为 public virtual Address Address {get;set;}
  • 也刚刚注意到。您的地址类已声明 guid CountryId,但在国家/地区类中它只是 Id。最好将您的 Id 声明为 {classname}Id 以清楚明确您引用的是哪个 Id
  • 实际上Address 类中的CountryId 属性足以让EFC 按照约定将其识别为对应于Country 导航属性的FK。所以关系 is 确实是用外键 (Person.Address_CountryId -> Country.Id) 创建的。有什么问题?
  • @WilkovanderVeen virtual 因为:它允许实体框架围绕虚拟属性创建代理,以便该属性可以支持延迟加载和更有效的更改跟踪
  • 您有多确定这确实是CountryAddress 之间的一对一关系?一对多更有意义(许多地址可以指同一个国家);并且您的实体 classes 的当前定义与一对多关系一致。您是否真的希望添加相同的国家代码多次次,如果您例如在特定国家有多个地址?这样做有什么好处?

标签: c# entity-framework-core


【解决方案1】:

EF Core 为一对一关系提供了 2 个流畅的 API - HasForeignKeyHasPrincipalKey

与一对多 API 的主要区别在于您需要显式提供泛型类型参数,因为关系的主体和依赖端不能由HasOne / WithOne 调用确定(对于一对多,一个始终是主体,许多是从属)。在这种情况下,导航属性无关紧要:

addressBuilder.HasOne(address => address.Country)
   .WithOne()
   .HasForeignKey<Address>(address => address.CountryId)

参考:Relationships

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    相关资源
    最近更新 更多