gpt4 book ai didi

c# - Entity Framework 有时不加载子对象/集合的内容

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

我开始遇到一个问题,即 Entity Framework 中的子集合没有通过延迟加载正确加载。

最突出的例子是我的 Orders 对象 - 每个订单都有一个或多个与之关联的订单行(即已订购的产品列表和数量)。有时,当程序运行时,您可以打开一些订单,并且所有订单行(对于每个订单)都会是空白的。重新启动程序,它们可能会重新出现。这是非常间歇性的。

我已经通过日志记录和调试确认子集合中没有条目:

    private ObservableCollection<OrderLine> LoadOrderLines()
{
Log.Debug("Loading {0} order lines...", this.Model.OrderLines.Count);

var result = new ObservableCollection<OrderLine>();

foreach (var orderLine in this.Model.OrderLines)
{
result.Add(orderLine);
}

return result;
}

有时它会为同一订单显示“正在加载 0 个订单行...”,有时会显示“正在加载 4 个订单行...”。

我在加载订单列表时无法使用 Eager Loading,因为我不想在只有少数订单被打开时加载所有订单的所有订单行 - 我需要保持加载速度尽可能快可能并且只在需要时加载东西,因此延迟加载。

它不仅发生在 Orders 对象上,有时也会发生在其他子集合上,但效果完全相同。

任何人都知道为什么 EF 这样做以及我可以做些什么来解决它?这是一个大问题 - 我的程序中不能有空的订单行,而它们应该在那里!

可能有用也可能没用的额外信息:

这是一个 WPF MVVM 应用程序。与网站共享的数据层使用存储库/工作单元模式。

在订单库中:
    public IEnumerable<Order> GetOrders(DateTime fromDate, DateTime toDate, IEnumerable<string> sources, bool? paidStatus, bool? shippedStatus, bool? cancelledStatus, bool? pendingStatus)
{
if (sources == null)
{
sources = this.context.OrderSources.Select(s => s.SourceId);
}

return
this.context.Orders.Where(
o =>
o.OrderDate >= fromDate
&& o.OrderDate < toDate
&& sources.Contains(o.SourceId)
&& (!paidStatus.HasValue || ((o.ReceiptId != null) == paidStatus.Value))
&& (!shippedStatus.HasValue || ((o.ShippedDate != null) == shippedStatus.Value))
&& (!pendingStatus.HasValue || (o.IsPending == pendingStatus.Value))
&& (!cancelledStatus.HasValue || (o.Cancelled == cancelledStatus.Value))).OrderByDescending(
o => o.OrderDate);
}

OrdersViewModel 然后加载订单,为每个订单创建一个 orderViewModel 并将它们放入 ObservableCollection 中:
var ordersList = this.unitOfWork.OrdersRepository.GetOrders(this.filter).ToList();

foreach (var order in ordersList)
{
var viewModel = this.viewModelProvider.GetViewModel<OrderViewModel, Order>(order);

this.orders.Add(viewModel);
}

最佳答案

延迟加载用于在您访问导航属性时自动加载相关实体。但是,在这种情况下,您不是自动执行的,而是手动执行的。

为此,您可以禁用延迟加载,并使用显式加载,如下所示:

context.Entry(order).Collection(o => o.orderLines).Load();

(此外,使用此技术,您可以应用过滤器)。

您的延迟加载问题可能是长期存在的结果 DbContext在给定的时间点缓存相关实体,并在稍后重用此缓存,而不会触及数据库,因此它已经过时了。 IE。一个 DbContext 为一个订单找到 3 个订单行并缓存它们。其他东西(在 db 上下文之外),为此订单添加了 2 个额外的新订单行。然后您从第一个 db 上下文访问订单行并获得过时的 3 个订单行,而不是数据库中的 5 个。从理论上讲,有多种方法可以重新加载/刷新 DbContext 上的缓存数据,但您可能会遇到麻烦。您宁愿使用我上面建议的显式加载。如果您看到 docs for Load method ,你可以阅读这个:

Loads the collection of entities from the database. Note that entities that already exist in the context are not overwritten with values from the database.



但是,最安全的选择始终是处理 DbContext并创建一个新的。 (阅读上面块的第二句话)。

关于c# - Entity Framework 有时不加载子对象/集合的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23969788/

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