Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架有时不加载子对象/集合的内容_C#_.net_Wpf_Entity Framework_Mvvm - Fatal编程技术网

C# 实体框架有时不加载子对象/集合的内容

C# 实体框架有时不加载子对象/集合的内容,c#,.net,wpf,entity-framework,mvvm,C#,.net,Wpf,Entity Framework,Mvvm,我开始遇到一个问题,即实体框架中的子集合没有通过延迟加载正确加载 最突出的例子是我的订单对象-每个订单都有一个或多个与之关联的订单行(即,已订购哪些产品以及订购了多少产品的列表)。有时,当程序运行时,您可以打开一些订单,所有订单行(针对每个订单)都将为空。重新启动程序,它们可能会重新出现。这是相当间歇的 我已通过日志记录和调试确认子集合中没有条目: private ObservableCollection<OrderLine> LoadOrderLines() {

我开始遇到一个问题,即实体框架中的子集合没有通过延迟加载正确加载

最突出的例子是我的订单对象-每个订单都有一个或多个与之关联的订单行(即,已订购哪些产品以及订购了多少产品的列表)。有时,当程序运行时,您可以打开一些订单,所有订单行(针对每个订单)都将为空。重新启动程序,它们可能会重新出现。这是相当间歇的

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

    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;
    }
private observeCollection LoadOrderLines()
{
Log.Debug(“正在加载{0}订单行…”,this.Model.OrderLines.Count);
var结果=新的ObservableCollection();
foreach(此.Model.OrderLines中的var orderLine)
{
结果.添加(订单行);
}
返回结果;
}
对于同一订单,有时会显示“加载0个订单行…”,有时会显示“加载4个订单行…”

当我加载订单列表时,我不能使用快速加载,因为我不想在只有少数订单可能被打开时加载所有订单的所有订单行-我需要尽可能快地加载,只加载需要的东西,因此延迟加载

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

有人知道EF为什么这么做,我能做些什么来修复它吗?这是一个巨大的问题-我不能在我的程序中有空的订单行,当他们应该在那里

可能有用或不有用的额外信息:

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

在OrdersRepository中:

    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);
    }
public IEnumerable GetOrders(日期时间fromDate,日期时间toDate,IEnumerable sources,bool?paidStatus,bool?shippedStatus,bool?Cancelled Status,bool?pendingStatus)
{
if(sources==null)
{
sources=this.context.OrderSources.Select(s=>s.SourceId);
}
返回
这是context.Orders.Where(
o=>
o、 OrderDate>=fromDate
&&o.OrderDateo.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);
        }
var ordersList=this.unitOfWork.ordersepository.GetOrders(this.filter.ToList();
foreach(ordersList中的变量顺序)
{
var viewModel=this.viewModelProvider.GetViewModel(订单);
this.orders.Add(viewModel);
}

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

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

context.Entry(order).Collection(o => o.orderLines).Load();
(此外,使用此技术,您可以应用过滤器)

延迟加载的问题可能是一个长期存在的
DbContext
的结果,它在给定的时间点缓存相关的实体,并在以后重用此缓存,而不会命中数据库,因此它已经过时。即,一个DbContext为一个订单找到3个订单行并缓存它们。另外,(在db上下文之外)向该订单添加2个额外的新订单行。然后从第一个db上下文访问订单行,并获取过期的3个订单行,而不是db中的5个订单行。从理论上讲,有几种方法可以重新加载/刷新DbContext上的缓存数据,但您可能会遇到麻烦。您宁愿使用我上面建议的显式加载。如果您看到,您可以阅读以下内容:

从数据库加载实体集合。请注意,上下文中已经存在的实体不会被数据库中的值覆盖


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

周六的帖子很长,但是,也许你必须使用方法
Include
,必须是延迟加载。我的回答解决了你的问题吗?