EF Core单向自引用实体绑定 [英] EF Core one-way self referencing entity binding
问题描述
我已经使用EF Core建立了一个自我参照实体,如下所示:
I have set up a self referential entity using EF Core which looks like this:
实体
public class DetailType
{
public int DetailTypeId { get; set; }
public string Name { get; set; }
public int? ParentTypeId { get; set; }
public DetailType ParentType { get; set; }
public IEnumerable<DetailType> ChildTypes { get; set; }
}
绑定
modelBuilder.Entity<DetailType>()
.ToTable("detailtype")
.HasOne(x => x.ParentType)
.WithMany(x => x.ChildTypes)
.HasForeignKey(x => x.ParentTypeId);
我正在通过API检索这些实体,当前结果如下所示:
I am retrieving these entities via an API and the current result looks something like this:
[
{
"detailTypeId": 20,
"name": "Money",
"parentTypeId": null,
"parentType": null,
"childTypes": null
},
{
"detailTypeId": 22,
"name": "Optional Extra",
"parentTypeId": null,
"parentType": null,
"childTypes": [
{
"detailTypeId": 42,
"name": "Extra Nights",
"parentTypeId": 22,
"childTypes": null
}
]
},
{
"detailTypeId": 42,
"name": "Extra Nights",
"parentTypeId": 22,
"parentType": {
"detailTypeId": 22,
"name": "Optional Extra",
"parentTypeId": null,
"parentType": null,
"childTypes": []
},
"childTypes": null
}
]
我遇到的问题是数组中的第三项与第二项相反.有没有一种方法可以避免这种情况,所以我只有父母->子女关系,而不是父母->子女以及子女->父母.上面的示例是我的API实际上返回的内容的简化版本,因此我想尽可能减少不必要的膨胀,因为会发生很多关系.
The problem I have with this is that the third item in the array is just the reverse of the second. Is there a way to avoid this so that I only have the parent -> child relationship rather than both parent -> child as well as child -> parent. The example above is a heavily cut-down version of what my API is actually returning so I want to reduce the unnecessary bloat as much as possible because there'll be a lot of relationships going on.
理想情况下,我想要的是摆脱ParentType属性,但仍然拥有ChildTypes集合,但是我不确定如何在模型构建器中定义它.
Ideally what I want is to just get rid of the ParentType property but still have the ChildTypes collection but I'm not sure how to define that in the model builder.
我已删除不需要的流畅关系.我还尝试了以下方法:
I have removed the fluent relationship as it's not needed. I've also tried the following:
var roots = this.Items.Where(x => x.ParentTypeId == null);
foreach (var root in roots)
{
root.ChildTypes = this.Items.Where(x => x.ParentTypeId == root.DetailTypeId);
}
return roots.ToList();
(顺便说一下, this.Items
是DbSet)
(this.Items
is the DbSet by the way)
但是,这需要将 ChildTypes
更改为 IQueryable
,当我这样做时,会出现以下异常:
However this requires changing ChildTypes
to an IQueryable
and when I do that I get the following exception:
实体类型上导航属性'ChildTypes'的类型"DetailType"是"EntityQueryable",未实现ICollection.集合导航属性必须实现目标类型的ICollection<>.
The type of navigation property 'ChildTypes' on the entity type 'DetailType' is 'EntityQueryable' which does not implement ICollection. Collection navigation properties must implement ICollection<> of the target type.
推荐答案
第一件事-您无需在模型构建器中指定此关系.它可以自行解决.
First things first - you don't need to specify this relation(s) in the model builder. It figures it out on its own.
然后关于您的问题-我想到的第一件事(我不知道您的整个数据集)是获取所有具有 ParentTypeId ==的
. DetailType
对象空
Then regarding your question - the first thing, that comes to my mind (I don't know your entire dataset) is to get all the DetailType
objects, that have ParentTypeId == null
.
这样,您将获得根,然后递归地构建子元素的 tree
.
By this you will get the roots, and then, recursively build the tree
of child elements.
这样做将清理您的结果,并且您将看到想要看到的结构.
Doing this will clean-up your result, and you will see the structure as you want to see it.
这篇关于EF Core单向自引用实体绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!