EF Core单向自引用实体绑定

时间:2018-09-25 15:49:47

标签: c# entity-framework asp.net-core entity-framework-core self-referencing-table

我已经使用EF Core建立了一个自我参照实体,如下所示:

实体

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检索这些实体,当前结果如下所示:

[
    {
        "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实际上返回的内容的简化版本,因此我想尽可能减少不必要的膨胀,因为会发生很多关系。

理想情况下,我想要摆脱的是ParentType属性,但仍然具有ChildTypes集合,但是我不确定如何在模型构建器中定义它。

编辑:

我已删除不需要的流畅关系。我还尝试了以下方法:

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)

但是,这需要将ChildTypes更改为IQueryable,当我这样做时,出现以下异常:

  

实体类型上导航属性'ChildTypes'的类型   “ DetailType”是“ EntityQueryable”,未实现   ICollection。集合导航属性必须   实现目标类型的ICollection <>。

1 个答案:

答案 0 :(得分:0)

首先,您不需要在模型构建器中指定此关系。它可以自行解决。

然后关于您的问题-我想到的第一件事(我不知道您的整个数据集)是获取所有具有DetailType的{​​{1}}对象。

这样,您将获得根源,然后递归构建子元素的ParentTypeId == null

这样做将清理您的结果,并且您将看到想要看到的结构。