繁体   English   中英

如何配置版本化实体之间的一对多/多对一关系

[英]How to configure a one-to-many/many-to-one relationship between versioned entities

我获得了(因此我无法更改它)一个数据库,其中包含使用version号列进行版本控制的实体。

实体是PersonDomicileAddress 每个实体都有一个由 id 和 version 组成的复合主键。

一个可以有多个住所,一个住所引用一个地址 一个地址可以被不同的住所引用。 因此,我们在Person和它的Domiciles之间存在一对多的关系,在DomicileAddress之间存在多对一的关系。

每个实体仅使用 id 引用另一个实体,因此每个实体都是独立版本的。

让我举几个表的例子:

|id|version|etc.
|1 |1      |...
|1 |2      |...

住所

|id|version|person_id|address_id|etc...
|2 |1      |1        |3         |...
|2 |2      |1        |3         |...
|3 |1      |1        |4         |...

地址

|id|version|etc...
|3 |1      |...
|3 |2      |...
|4 |1      |...

如您所见,每个实体仅使用 id 相互引用,并且同一实体可以有多个版本,因此您可以多次使用相同的 id。

我希望我的 model 实体看起来像:

public class Person {
  public long Id {get; set;}
  public long Version {get; set;}
  public List<Domicile> Domiciles {get; set;}
}

public class Domicile {
  public long Id {get; set;}
  public long Version {get; set;}
  public long AddressId {get; set;}
  public List<Address> AddressVersions {get; set;}
}

public class Address {
  public long Id {get; set;}
  public long Version {get; set;}
}

配置一个人与其住所之间的关系很简单:

modelBuilder.Entity<Person>(entity => {
  //...
  entity.HasMany(p => p.Domiciles)
    .WithOne()
    .HasForeignKey(d => d.PersonId)
    .HasPrincipalKey(p => p.Id);
});

现在是我不知道如何配置的部分: Domicile与其地址版本之间的关系。 从理论上讲,这种关系应该是多对一的,因为一个Address被多个Domiciles使用。

我想在 Domicile 上拥有所有地址版本,所以我已经声明了属性public List<Address> AddressVersions ,但现在我必须配置导航属性。

如果我尝试将关系配置为:

modelBuilder.Entity<Domicile>(entity => {
  //...
  entity.HasMany(p => p.AddressVersions)
    .WithMany());
});

这不会编译,因为多对多关系需要双方都有导航属性。

如果我尝试将 model 与一对多配置的关系:

modelBuilder.Entity<Domicile>(entity => {
  //...
  entity.HasMany(p => p.AddressVersions)
    .WithOne()
    .HasPrincipalKey(p => p.AddressId);
});

它不起作用,因为我在Address上没有引用Domicile的外键,因为Address被多个Domiciles使用。

如果我 go 与关系相反:

modelBuilder.Entity<Domicile>(entity => {
  //...
  entity.HasOne(p => p.Address)
    .WithMany()
    .HasForeignKey(p => p.AddressId)
    .HasPrincipalKey(d => d.Id);
});

尽管有这些工作,但我只得到了Address的许多可能版本之一,丢失了信息。

我怎样才能 model地址住所之间的这种关系,并在主体实体上提供相关实体的所有版本?

简短的回答是您想要的功能无法通过内置功能完成。 也许第三方扩展/工具可以提供帮助。

Id对于您的三个实体中的任何一个都不是唯一的,因此您不能仅使用Id属性作为主键在它们之间建立多对一或一对多关系(因为主键必须唯一标识相关记录) .

选项:

  1. 手动加入这些实体并投影结果
  2. 创建数据库视图(如果允许)以提供 EF 可用于多对多关系的联结实体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM