如何在 Entity Framework Core 中设置多个 one-to-one 关系?
How to set up multiple one-to-one relationships in Entity Framework Core?
我有两个实体 Parent
和 Child
;每个 parent 最多可以有两个 child 引用。我已按如下方式设置我的实体:
class Parent
{
[Key]
public int ParentId { get; set; }
public int PrimaryChildId{ get; set; }
public Child PrimaryChild { get; set; }
public int SecondaryChildId { get; set; }
public Child? SecondaryChild { get; set; }
// remaining properties
}
class Child
{
[Key]
public int ChildId { get; set; }
public int ParentId { get; set; }
public Parent Parent {get; set; }
// remaining child properties
}
在 DbContext.OnModelCreating
我有这个代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>(builder =>
{
builder.HasOne(p => p.PrimaryChild);
builder.HasOne(p => p.SecondaryChild);
});
}
这还不足以实现我在这里想要实现的目标。我得到一个错误:
Unable to determine the relationship represented by navigation property 'Child.Parent' of type 'Parent'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'
我尝试从 Child
实体建立关系,但我得到了不同的错误,因为这让我为同一个 属性 建立了两个关系。我不想在我的 child 上有两个导航属性,因为我知道一次只能使用一个导航属性,因为这会导致模型混乱。
我在互联网上搜索了一下,但没有找到以这种方式建立的关系。
过去几天我一直在尝试类似的方法,在尝试了各种数据注释和 Fluent API 废话之后,我能想出的最干净的解决方案竟然非常简单这两者都不需要。它只需要将 'private' 构造函数添加到注入 'DbContext' 对象的父对象 class (如果您使用延迟加载,则添加 'protected' 构造函数)。只需将 'Parent' 和 'Child' classes 设置为正常的一对多关系,并且现在可以从 'Parent' 实体中获得数据库上下文,您可以使用 Find() 方法使 'PrimaryChild' 和 'SecondaryChild' 简单地 return 从数据库中查询。 Find() 方法也使用缓存,因此如果您多次调用 getter,它只会访问数据库一次。
这是关于此能力的文档:https://docs.microsoft.com/en-us/ef/core/modeling/constructors#injecting-services
注意:'PrimaryChild' 和 'SecondaryChild' 属性是只读的。要修改它们,请设置 'PrimaryChildId' 和 'SecondaryChildId' 属性。
class Parent
{
public Parent() { }
private MyDbContext Context { get; set; }
// make the following constructor 'protected' if you're using Lazy Loading
private Parent(MyDbContext Context) { this.Context = Context; }
[Key]
public int ParentId { get; set; }
public int PrimaryChildId { get; set; }
public Child PrimaryChild { get { return Context.Children.Find(PrimaryChildId); } }
public int? SecondaryChildId { get; set; }
public Child SecondaryChild { get { return Context.Children.Find(SecondaryChildId); } }
// remaining properties
}
class Child
{
[Key]
public int ChildId { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
// remaining child properties
}
我有两个实体 Parent
和 Child
;每个 parent 最多可以有两个 child 引用。我已按如下方式设置我的实体:
class Parent
{
[Key]
public int ParentId { get; set; }
public int PrimaryChildId{ get; set; }
public Child PrimaryChild { get; set; }
public int SecondaryChildId { get; set; }
public Child? SecondaryChild { get; set; }
// remaining properties
}
class Child
{
[Key]
public int ChildId { get; set; }
public int ParentId { get; set; }
public Parent Parent {get; set; }
// remaining child properties
}
在 DbContext.OnModelCreating
我有这个代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>(builder =>
{
builder.HasOne(p => p.PrimaryChild);
builder.HasOne(p => p.SecondaryChild);
});
}
这还不足以实现我在这里想要实现的目标。我得到一个错误:
Unable to determine the relationship represented by navigation property 'Child.Parent' of type 'Parent'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'
我尝试从 Child
实体建立关系,但我得到了不同的错误,因为这让我为同一个 属性 建立了两个关系。我不想在我的 child 上有两个导航属性,因为我知道一次只能使用一个导航属性,因为这会导致模型混乱。
我在互联网上搜索了一下,但没有找到以这种方式建立的关系。
过去几天我一直在尝试类似的方法,在尝试了各种数据注释和 Fluent API 废话之后,我能想出的最干净的解决方案竟然非常简单这两者都不需要。它只需要将 'private' 构造函数添加到注入 'DbContext' 对象的父对象 class (如果您使用延迟加载,则添加 'protected' 构造函数)。只需将 'Parent' 和 'Child' classes 设置为正常的一对多关系,并且现在可以从 'Parent' 实体中获得数据库上下文,您可以使用 Find() 方法使 'PrimaryChild' 和 'SecondaryChild' 简单地 return 从数据库中查询。 Find() 方法也使用缓存,因此如果您多次调用 getter,它只会访问数据库一次。
这是关于此能力的文档:https://docs.microsoft.com/en-us/ef/core/modeling/constructors#injecting-services
注意:'PrimaryChild' 和 'SecondaryChild' 属性是只读的。要修改它们,请设置 'PrimaryChildId' 和 'SecondaryChildId' 属性。
class Parent
{
public Parent() { }
private MyDbContext Context { get; set; }
// make the following constructor 'protected' if you're using Lazy Loading
private Parent(MyDbContext Context) { this.Context = Context; }
[Key]
public int ParentId { get; set; }
public int PrimaryChildId { get; set; }
public Child PrimaryChild { get { return Context.Children.Find(PrimaryChildId); } }
public int? SecondaryChildId { get; set; }
public Child SecondaryChild { get { return Context.Children.Find(SecondaryChildId); } }
// remaining properties
}
class Child
{
[Key]
public int ChildId { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
// remaining child properties
}