繁体   English   中英

ASP.NET Core Web API 无法返回使用 EF Core 延迟加载提取的结果

[英]ASP.NET Core Web API can not return results extracted using EF Core lazy-loading

我正在探索 EF Core 延迟加载,但很难通过 ASP.NET Web API 返回结果。 请在下面检查我的 API 调用。

// GET: api/Supplier
[HttpGet("/GetSupplierUsingLazyLoading")]
public async Task<ActionResult<Supplier>> GetSupplierUsingLazyLoading()
{
    var products = _context.Products.ToList();
    var supplier = products.Last().Supplier;

    return await Task.FromResult(supplier);
    //return await Task.FromResult(new Supplier());
}

是的。 我添加了包Microsoft.EntityFrameworkCore.Proxies

我在Startup.cs添加了UseLazyLoadingProxies

services.AddDbContext<NorthwindContext>(
        options =>
        {
            options.UseMySql(Configuration.GetConnectionString("Northwind_MySQL"), Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.23-mysql"));
            options.UseLazyLoadingProxies();
            options.LogTo(Console.WriteLine, LogLevel.Information);
        }
    );

我使用Pomelo.EntityFrameworkCore.MySql作为数据库提供者。

当我从 swagger 调用 Web API 时,它会在幕后进行大量数据库调用。 这是我在终端看到的。 它一直在打这些电话。 我不得不停止应用程序来停止这些调用。 我不确定我在这里做错了什么。 还有其他人面临这个问题吗?

info: 6/26/2021 08:01:55.859 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (1ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT `o`.`OrderDetailsID`, `o`.`Discount`, `o`.`OrderID`, `o`.`ProductID`, `o`.`Quantity`, `o`.`UnitPrice`
      FROM `orderdetails` AS `o`
      WHERE `o`.`OrderID` = @__p_0
info: 6/26/2021 08:01:55.863 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT `o`.`OrderDetailsID`, `o`.`Discount`, `o`.`OrderID`, `o`.`ProductID`, `o`.`Quantity`, `o`.`UnitPrice`
      FROM `orderdetails` AS `o`
      WHERE `o`.`OrderID` = @__p_0
info: 6/26/2021 08:01:55.867 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT `o`.`OrderDetailsID`, `o`.`Discount`, `o`.`OrderID`, `o`.`ProductID`, `o`.`Quantity`, `o`.`UnitPrice`
      FROM `orderdetails` AS `o`
      WHERE `o`.`OrderID` = @__p_0
info: 6/26/2021 08:01:55.870 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT `o`.`OrderDetailsID`, `o`.`Discount`, `o`.`OrderID`, `o`.`ProductID`, `o`.`Quantity`, `o`.`UnitPrice`
      FROM `orderdetails` AS `o`
      WHERE `o`.`OrderID` = @__p_0
info: 6/26/2021 08:01:55.876 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (1ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT `o`.`OrderDetailsID`, `o`.`Discount`, `o`.`OrderID`, `o`.`ProductID`, `o`.`Quantity`, `o`.`UnitPrice`
      FROM `orderdetails` AS `o`
      WHERE `o`.`OrderID` = @__p_0

当我使用return await Task.FromResult(new Supplier()); 然后它返回一个空的供应商。

感谢好奇驱动

首先:请记住,延迟加载是一项仅在需要时从数据库中检索数据的功能,应非常小心地使用。

考虑到这一点,让我们谈谈您的模型。 假设您有一个Supplier 由于您总是从供应商那里购买东西,因此该供应商必须与某些Orders ,对吗? 所有Orders都有OrderItems并且这些项目中的每一个都与一个Product相关。 所以我们以这样的模型图结束:

在此处输入图片说明

你的课程应该是这样的

public class Supplier
{
    public string Name { get; set; }
    List<Order> Orders { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
}

public  class OrderItem
{
    public int OrderItemId { get; set; }
    public int ProductId { get; set; }
    public Product Product { get; set; }

    public int OrderId { get; set; }
    public Order Order { get; set; }
}

public class Order 
{
    public decimal FinalPrice { get; set; }
    public int SupplierId { get; set; }
    public Supplier Supplier { get; set; }
    List<OrderItem> OrderItems { get; set; }
}

当您尝试序列化来自数据库的 Supplier 时,它也会序列化它的Orders ,然后是OrderItems ,最后是Product因为您的完整对象图已序列化。

还记得数据只在需要时从数据库中检索吗? 好吧,序列化器一次序列化每个节点,因此如果您有 4 个订单项,它将向数据库询问 4 次产品 4 次。

当您序列化new Supplier()这不会发生,原因有两个。 EntityFramework 不跟踪new Supplier() ,因此不会进行任何查询,即使跟踪了该供应商,该供应商也没有订单,因此不会运行其他查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM