我得到了一个数据库(因此我不能更改它),该数据库包含使用version
数字列进行版本控制的实体.
实体为人、住所、地址.这些实体中的每个实体都有一个由id和版本组成的复合主键.
人可以有多个住所s,住所引用地址.地址可以由不同的住所s引用.因此,我们在人和住所s之间存在一对多关系,在住所和地址之间存在多对一关系.
每个实体只使用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.
我希望我的模型实体看起来类似于:
public class 人 {
public long Id {get; set;}
public long Version {get; set;}
public List<住所> 住所s {get; set;}
}
public class 住所 {
public long Id {get; set;}
public long Version {get; set;}
public long 地址Id {get; set;}
public List<地址> 地址Versions {get; set;}
}
public class 地址 {
public long Id {get; set;}
public long Version {get; set;}
}
配置一个人与其住所之间的关系很简单:
modelBuilder.Entity<人>(entity => {
//...
entity.HasMany(p => p.住所s)
.WithOne()
.HasForeignKey(d => d.人Id)
.HasPrincipalKey(p => p.Id);
});
Now comes the part that I have no clue how to configure: the relationship between a 住所 and its 地址 versions. In theory this relation should be a many-to-one because one 地址 is used by multiple 住所s.
I want to have ALL the 地址 versions on the 住所 so I've declared the property public List<地址> 地址Versions
, but now I have to configure the navigation property.
如果我try 将关系配置为:
modelBuilder.Entity<住所>(entity => {
//...
entity.HasMany(p => p.地址Versions)
.WithMany());
});
这将无法编译,因为多对多关系需要两端都有导航属性.
如果我try 使用一对多配置对关系进行建模:
modelBuilder.Entity<住所>(entity => {
//...
entity.HasMany(p => p.地址Versions)
.WithOne()
.HasPrincipalKey(p => p.地址Id);
});
It will not work because I don't have a foreign key on 地址 that refers to 住所 given that an 地址 is used by multiple 住所s.
如果我用另一种方式处理这段关系:
modelBuilder.Entity<住所>(entity => {
//...
entity.HasOne(p => p.地址)
.WithMany()
.HasForeignKey(p => p.地址Id)
.HasPrincipalKey(d => d.Id);
});
Despite this works I get just one of the many possibile versions of an 地址, losing information.
How can I model such relations like between 地址 and 住所 and making available on the principal entity all the versions of the related entity ?
编辑:
对数据的一些澄清:
每个实体都有一个复合主键,定义如下:
PRIMARY KEY (id, version);
此复合主键唯一标识特定记录和版本.
每个实体使用如下定义的外键引用另一个实体:
CREATE TABLE 住所(
--etc.
CONSTRAINT fk_address FOREIGN KEY (address_id) REFERENCES address (id)
);
正如您所看到的,外键只引用了主键的一部分.
In the example table that I provided above I expect that when I select 人 with id 1
and version 2
I get 3 domiciles back (id 2
and the two versions 1
and 2
and id 3
with just one version).
Then, for every version of domicile with id 2
, I expect 2 addresses (id 3
with version 1
and 2
) and for the single version of domicile with id 3
I exepect 1 address (id 4
with version 1
)
In code we could write my expectation for 住所 with id 2
as:
Assert.That(domicile.地址es.Count, Is.EqualTo(3));
Assert.That(domicile.地址es[0].Id, Is.EqualTo(3));
Assert.That(domicile.地址es[0].Version, Is.EqualTo(1));
Assert.That(domicile.地址es[1].Id, Is.EqualTo(3)); //Same address id as before...
Assert.That(domicile.地址es[0].Version, Is.EqualTo(2)); //...but different version
问题似乎是,外键不引用唯一行,因为它只使用了part个主键,因此这种关系不能用实体框架核心建模(也许?).
希望这能更好地阐明我必须处理什么以及我想要得到什么.