我有 2 个类,我想避免使用导航属性。
所以代替:
public class A
{
public int Id { get; private set; }
public B B { get; private set; }
}
public class B
{
public int Id { get; private set;}
public A A { get; private set;}
}
我想要这样的东西:
public class A
{
public int Id { get; private set; }
//optional and instead of navigational property
public int? BId { get; private set; }
}
public class B
{
public int Id { get; private set;}
//optional and instead of navigational property
public int? AId { get; private set;}
}
如何配置它们之间的关系,以便每当我从数据库加载
A
或 B
的实例时,外部 ID 都会正确加载?
您的第一个示例意味着该关系是必需的,因为 A.B 和 B.A 不可为空,但是如果它们是可选的并且您只想拥有包含 FK 的实体,那就完全没问题,并且如果使用模式优先。
一对一关系以两种方式之一映射,要么是共享 PK,要么是一侧具有 FK 且具有唯一约束的多对一。因此,对于 FK 字段,您要么拥有 A.BId,要么拥有 B.AId,而不是两者兼而有之。没有两者的原因是不可能强制 B 记录 A.BId 具有指向回的 AId。 ID #1 的 BId 可以为 1,但 B ID #1 的 AId 可以为 2。
考虑到这一点,您可以在一张表上设置可为空的 FK 并映射实体中的列。
如果您想使用代码优先,那么 EF Core 中也提供了此功能:
builder.Entity<A>
.HasOne<B>()
.WithOne<A>()
.HasForeignKey<A>(a => a.BId) // or .HasForeignKey<B>(b => b.AId)
.IsRequired(false);
如果 A 持有 BId 并且您想要给定 B 记录的 AId/A,您需要从 As 查询它:(如果 A 持有 FK)
var a = context.As.Where(a => a.BId == bId).Single();
选择最常作为聚合根的一侧来持有 FK。阅读 A 并想了解其 B,或者阅读 B 并想了解其 A 是否更有意义?