gpt4 book ai didi

performance - 我可以在 EntityFramework 中的 ObjectSet 上使用多少个 Include 以保持性能?

转载 作者:行者123 更新时间:2023-12-03 06:12:16 24 4
gpt4 key购买 nike

我对我的个人资料页面使用以下 LINQ 查询:

var userData = from u in db.Users
.Include("UserSkills.Skill")
.Include("UserIdeas.IdeaThings")
.Include("UserInterests.Interest")
.Include("UserMessengers.Messenger")
.Include("UserFriends.User.UserSkills.Skill")
.Include("UserFriends1.User1.UserSkills.Skill")
.Include("UserFriends.User.UserIdeas")
.Include("UserFriends1.User1.UserIdeas")
where u.UserId == userId
select u;

它有一个很长的对象图并使用许多包含。目前运行完美,但是当网站用户较多时,对性能影响大吗?

我应该用其他方式来做吗?

最佳答案

包含的查询返回单个结果集,包含的数量会影响大数据集从数据库服务器传输到 Web 服务器的方式。示例:

假设我们有一个实体Customer(Id、Name、Address)和一个实体Order(Id、CustomerId、Date)。现在我们要查询客户的订单:

var customer = context.Customers
.Include("Orders")
.SingleOrDefault(c => c.Id == 1);

生成的数据集将具有以下结构:

 Id | Name | Address | OrderId | CustomerId | Date 
---------------------------------------------------
1 | A | XYZ | 1 | 1 | 1.1.
1 | A | XYZ | 2 | 1 | 2.1.

这意味着每个订单都会重复Cutomers数据。现在让我们使用另一个实体扩展该示例 -“OrderLine (Id, OrderId, ProductId, Quantity)andProduct (Id, Name)”。现在我们要查询客户的订单、订单行和产品:

var customer = context.Customers
.Include("Orders.OrderLines.Product")
.SingleOrDefault(c => c.Id == 1);

生成的数据集将具有以下结构:

 Id | Name | Address | OrderId | CustomerId | Date | OrderLineId | LOrderId | LProductId | Quantity | ProductId | ProductName
------------------------------------------------------------------------------------------------------------------------------
1 | A | XYZ | 1 | 1 | 1.1. | 1 | 1 | 1 | 5 | 1 | AA
1 | A | XYZ | 1 | 1 | 1.1. | 2 | 1 | 2 | 2 | 2 | BB
1 | A | XYZ | 2 | 1 | 2.1. | 3 | 2 | 1 | 4 | 1 | AA
1 | A | XYZ | 2 | 1 | 2.1. | 4 | 2 | 3 | 6 | 3 | CC

正如您所看到的,数据变得非常重复。通常,每个引用导航属性(示例中的 Product)的包含都会添加新列,并且每个包含到集合导航属性(OrdersOrderLines > 在示例中)将为包含的集合中的每一行添加新列并复制已创建的行。

这意味着您的示例可以轻松拥有数百列和数千行,这是需要传输的大量数据。正确的方法是创建性能测试,如果结果不能满足您的期望,您可以通过自己的查询或通过 LoadProperty 方法单独修改查询和加载导航属性。

单独查询的示例:

var customer = context.Customers
.Include("Orders")
.SingleOrDefault(c => c.Id == 1);
var orderLines = context.OrderLines
.Include("Product")
.Where(l => l.Order.Customer.Id == 1)
.ToList();

LoadProperty 示例:

var customer = context.Customers
.SingleOrDefault(c => c.Id == 1);
context.LoadProperty(customer, c => c.Orders);

此外,您应该始终只加载您真正需要的数据。

编辑:我刚刚创建了 proposal on Data UserVoice支持附加的急切加载策略,其中急切加载的数据将在附加结果集中传递(由同一数据库往返中的单独查询创建)。如果您发现此改进很有趣,请不要忘记投票支持该提案。

关于performance - 我可以在 EntityFramework 中的 ObjectSet 上使用多少个 Include 以保持性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5521749/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com