c# - EF 核心急切加载 - 多次加载相同的数据
问题描述
我有一个产品表和一个类别表。所有产品都有一个 FK-categoryId。如何停止多次加载数据?像这样:
班级:
public partial class Product
{
public Product()
{
OrderItem = new HashSet<OrderItem>();
ProductPictureMapping = new HashSet<ProductPictureMapping>();
}
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public partial class Category
{
public Category()
{
Product = new HashSet<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Product { get; set; }
}
控制器方法:
var allProduct = _context.Product
.Include("Category")
.ToListAsync();
输出:
它返回一个产品,然后是一个类别,然后是类别下的所有产品注意 ,我已经在 startup.cs Newtonsoft.Json.ReferenceLoopHandling.Ignore 中禁用了循环使用它;
[{
"id": 1,
"name": "Redmi Note 7",
"category": {
"id": 2,
"name": "Mobile",
"product": [
{
"id": 2,
"name": "Mi Note 9",
"category":null
}]
},
{
"id": 2,
"name": "Mi Note 9",
"category": {
"id": 1,
"name": "Redmi Note 7",
"category":null
}
}]
解决方案
您可以使用Data Transfer Object (DTO)
模型来摆脱创建这些参考循环的导航属性。
创建以下两个 DTO 模型 -
public class ProductDTO
{
public int Id { get; set; }
public string Name { get; set; }
public CategoryDTO Category { get; set; }
}
public class CategoryDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
然后在您的查询中使用投影,例如 -
var allProduct = dbCtx.Products
.Select(p => new ProductDTO
{
Id = p.Id,
Name = p.Name,
Category = new CategoryDTO
{
Id = p.Category.Id,
Name = p.Category.Name
}
});
如果您不需要在查询结果中键入对象,您可以在不创建任何 DTO 模型并在投影中使用匿名类型的情况下执行相同的操作,例如 -
var allProduct = dbCtx.Products
.Select(p => new
{
Id = p.Id,
Name = p.Name,
Category = new
{
Id = p.Category.Id,
Name = p.Category.Name
}
});
推荐阅读
- c# - 在 OWIN JWT OAuth 中使用 Clockskew 的正确方法
- java - DeferredResult 的 Spring MVC 单元测试不调用超时回调
- unity3d - 我怎样才能让我的机器人角色保持在飞机的边界内?
- html - 为同一页面上的多个表格格式化 CSS 样式
- ipython - 如何将 jupyter notebook (ipython) 转换为幻灯片而不使用命令行
- c# - WPF 等效于 Winform 的 KeyEventArgs - 使用特定键调用 KeyDown 事件
- python - ValueError:检查输入时出错:预期dense_16_input有2维,但得到的数组形状为(60000、28、28)
- ruby-on-rails - Ruby on Rails - 防止 rails 在注册之前创建会话 cookie
- javascript - React Native:如何在客户端存储聊天记录?
- node.js - 在 Elastic Beanstalk 和 AWS Lambda 上更新 nodejs API