gpt4 book ai didi

c# - Entity Framework 父子表仅返回直接子项

转载 作者:行者123 更新时间:2023-11-30 21:51:00 26 4
gpt4 key购买 nike

我有一个标准的父/子 EF 模型,如下所示

public class DataDictionary 
{
public int Id { get; set; }
public String Name { get; set; }

public int? ParentId { get; set; }

[JsonIgnore]
public virtual DataDictionary Parent { get; set; }

public virtual ICollection<DataDictionary> Children { get; set; }
}

我通过 WebApi 将其作为 REST api 公开,目前它将在我获取节点时返回完整的父子层次结构,如下所示。

{
"Id": 1,
"Name": "root",
"SegmentKey": null,
"ParentId": null,
"Children": [{
"Id": 2,
"Name": "Demographics",
"SegmentKey": null,
"ParentId": 1,
"Children": [{
"Id": 3,
"Name": "Gender",
"ParentId": 2,
"Children": []
}, {
"Id": 4,
"Name": "Age",
"ParentId": 2,
"Children": []
}, {
"Id": 5,
"Name": "Income",
"ParentId": 2,
"Children": []
}]
}, {
"Id": 6,
"Name": "Activity",
"SegmentKey": null,
"ParentId": 1,
"Children": [{
"Id": 7,
"Name": "Navigation",
"SegmentKey": null,
"ParentId": 6,
"Children": []
}, {
"Id": 8,
"Name": "Behaviour",
"SegmentKey": null,
"ParentId": 6,
"Children": []
}]
}]
}

但是,我只需要获取请求的对象和仅返回的直接子对象,以便我的消费者可以在用户浏览数据时构建可视化表示。

更新:感谢大家的评论,脱离虚拟后一切看起来都不错,但是我正在努力处理 .Include,因为我在一个异步方法中,其中 find 返回对象并且我丢失了上下文。即

    [ResponseType(typeof(DataDictionary))]
public async Task<IHttpActionResult> GetDataDictionary(int id)
{
DataDictionary dataDictionary = await db.DataDictionaries.FindAsync(id);
if (dataDictionary == null)
{
return NotFound();
}
return Ok(dataDictionary);
}

如有帮助将不胜感激

最佳答案

对您来说,这是因为您的实体中使用了“virtual”关键字。此关键字为您的集合启用延迟加载,因此当序列化程序开始序列化您的子集合时,它会尝试枚举此集合,从而导致它从数据库中加载。之后,这个集合中的每个元素都被递归序列化,导致每个子集合的负载从数据库加载(有 N+1 选择问题)。

做你想做的事你需要:

首先,从您的 Children 属性中删除 virtual 关键字:

public class DataDictionary 
{
public int Id { get; set; }
public String Name { get; set; }

public int? ParentId { get; set; }

[JsonIgnore]
public virtual DataDictionary Parent { get; set; }

public ICollection<DataDictionary> Children { get; set; }
}

其次,您需要提前将此集合加载到您的 Controller 中。此代码将只为您的 dataDictionary 类实例加载 1 个级别:

[ResponseType(typeof(DataDictionary))]
public async Task<IHttpActionResult> GetDataDictionary(int id)
{
DataDictionary dataDictionary = await db.DataDictionaries
.Include(x=>x.Children)
.FirstOrDefaultAsync(x=>x.Id == id);
if (dataDictionary == null)
{
return NotFound();
}
return Ok(dataDictionary);
}

不要忘记在文件开头添加 using System.Data.Entity 以访问 .Include() 函数。

此外,考虑不要在您的 api 中使用 Entity Framework 实体 - 最好创建 DTO,这将使您可以减少 API 对 DB 结构的依赖 - API 将只有 EF 实体的字段子集。您还可以在此处限制树的深度,创建一个没有子集合的子类。

希望这对您有所帮助!

关于c# - Entity Framework 父子表仅返回直接子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35948439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com