【问题标题】:EF core eager loading - loads same data multiple timesEF 核心急切加载 - 多次加载相同的数据
【发布时间】:2021-05-21 03:43:41
【问题描述】:

我有一个产品表和一个类别表。所有产品都有一个 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();

输出:

它返回一个产品,然后是一个类别,然后是 Category 下的所有产品 请注意,我已经在 startup.csNewtonsoft.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
       }
}]

【问题讨论】:

    标签: c# .net linq .net-core entity-framework-core


    【解决方案1】:

    您可以使用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
                }
            });
    

    【讨论】:

    • 你能在这种情况下使用你的逻辑帮助我吗...如果我想从这个 dto 中获取角色,那么 select 语句将如何。由于角色是 RoleDTO 的列表。public int Id { get; set; } public string Username { get; set; } public IList&lt;RoleDTO&gt; Roles { get; set; }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多