[英]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.