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

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

我正在探索 EF Core 延迟加载,但努力 return 结果优于 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()); 时,它 return 是一个空供应商。

谢谢 好奇的驱动器

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

考虑到这一点,让我们谈谈您的模型。 假设您有一个 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() 时,这不会发生有两个原因。 new Supplier() 未被 EntityFramework 跟踪,因此不会进行任何查询,即使被跟踪,该供应商也没有订单,因此不会有其他查询 运行.