使用 Entity Framework 和延迟加载减少加载时间

Reduce Load time with Entity Framework and Lazy loading

C# WinForms:我在 Entity framework v6.2.0 和 延迟加载 中使用代码优先方法,问题就是在我们的grid中加载数据需要4到5秒(只有第一次)。我想减少这个加载时间。有帮助吗?

public List<ShipmentOrder> GetShipmentOrder()
{    
    var ObjShipmentOrderResult = context.shipmentOrders.ToList();
    List<ShipmentOrderEntity> ObjShipmentOrder = null;

        if (ObjShipmentOrderResult != null)
        {
            ObjShipmentOrder = new List<ShipmentOrderEntity>();
            foreach (var item in ObjShipmentOrderResult)
            {
                context.Entry(item).Reference(e => e.storageGate).Load();
                context.Entry(item).Reference(e => e.shippingOrderStatus).Load();
                context.Entry(item).Reference(e => e.packingOrder).Load();
                ObjShipmentOrder.Add(item);
            }
            context.Database.Connection.Close();
            return AutoMapper.Mapper.Map<List<ShipmentOrder>>ObjShipmentOrder);
        }
        else
        {
            return null;
        }
}

使用 Automapper,您无需担心延迟加载:

public List<ShipmentOrderViewModel> GetShipmentOrder()
{    
    var query= context.shipmentOrders.AsQueryable();
    return query.ProjectTo<ShipmentOrderViewModel>().ToList();
}

ProjectTo 采用 IQueryable(EF 查询通常处理的内容,但在这种情况下,因为您使用的是完整的 DbSet,我们需要 AsQueryable())并将投影到可查询中以仅加载视图模型所需的数据。这将导致对数据库的优化查询,以加载填充视图模型列表所需的所有字段。

原始代码的一些味道:

显然,随着系统的增长,您需要限制这将拉回的记录数。随着记录数量的增加,简单地返回 DbSet 中的所有内容将很快成为一个大问题。

我已将返回对象的命名阐明为视图模型,以确保它与实体区分开来 class。在某些情况下,视图模型可能几乎将字段与实体一对一地映射,但是在 DbContext 范围之外传递实体充满了问题,甚至通过选择一个新的实体来兼顾实体,分离副本并将其视为视图模型是不可取的。 (一个实体 class 应该始终像一个实体一样对待,如果实体可能是分离的与附加的,或者数据的不完整表示,它会在路上变得混乱。)

最后,为什么要在上下文中显式关闭底层数据库连接?上下文的范围如何?如果您使用的是 Autofac、Unity、Ninject 等 IoC 容器,这应该在处理上下文时自动管理。前提是上下文限定在请求范围内。如果不是,上下文是在哪里构建的?如果需要关闭连接,则应使用 using() 块限定上下文的范围,直到您能够实现 IoC 容器来管理其生命周期。