简体   繁体   English

通过实体框架和延迟加载减少加载时间

[英]Reduce Load time with Entity Framework and Lazy loading

C# WinForms: I'm using code first approach with Entity framework v6.2.0 and lazy loading , the problem is that it takes 4 to 5 seconds (only the first time) to load the data in our grid . C#WinForms:我在Entity Framework v6.2.0和延迟加载中使用代码优先方法,问题是将数据加载到网格中需要4到5秒(仅是第一次)。 I would like to reduce this load time. 我想减少此加载时间。 Any help? 有什么帮助吗?

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;
        }
}

Using Automapper you don't need to worry about lazy loads: 使用Automapper,您无需担心延迟加载:

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

ProjectTo takes an IQueryable (what EF queries normally deal with, though in this case because you are using the full DbSet , we need the AsQueryable() ) and will project into that queryable to load just the data needed for your view model. ProjectTo接受一个IQueryable (EF查询通常处理的内容,尽管在这种情况下,因为您使用的是完整的DbSet ,所以我们需要AsQueryable() )并将投影到该可查询对象中,以仅加载视图模型所需的数据。 This will result in an optimized query to the database to load all the fields necessary to populate the list of view models. 这将导致对数据库的优化查询,以加载填充视图模型列表所需的所有字段。

A few smells from the original code: 原始代码有一些气味:

Obviously as the system grows you need to limit the # of records that this will pull back. 显然,随着系统的增长,您需要限制将拉回的记录数。 Simply returning everything in a DbSet will quickly become a big problem as the # of records increases. 随着记录数量的增加,仅返回DbSet所有内容将很快成为一个大问题。

I've clarified the naming for the returned object as a View Model to ensure that it differentiates from the Entity class. 我已经澄清了将返回的对象命名为“视图模型”,以确保它与Entity类有所区别。 In some cases the view model may pretty much map fields 1-to-1 with an entity, but passing entities outside of the scope of a DbContext is rife with issues, and even dual-purposing an entity by selecting a new, detached copy and treating it like a view model isn't advisable. 在某些情况下,视图模型可能会将实体与实体DbContext ,但是在DbContext范围之外传递实体会出现DbContext问题,甚至通过选择一个新的,分离的副本并双重目的来实体化实体。建议不要将其视为视图模型。 (An entity class should always be treated like an entity, it gets confusing down the road if entities may be detached vs. attached, or incomplete representations of data.) (实体类应始终被视为实体,如果实体可能是分离的,附加的或不完整的数据表示形式,则会使人迷惑。)

Lastly, why are you closing the underlying database connection in the context explicitly? 最后,为什么要在上下文中显式关闭基础数据库连接? How is the context scoped? 上下文的范围如何? If you are using an IoC container like Autofac, Unity, Ninject, etc. this should be managed automatically as the context is disposed. 如果您使用的是IoC容器,例如Autofac,Unity,Ninject等,则应在处理上下文时自动对其进行管理。 Provided the context is scoped to the request. 前提是上下文范围是请求的范围。 If not, where is the context constructed? 如果没有,上下文在哪里构造? If there is a need to close the connection then the context should be scoped with a using() block until you are able to implement an IoC container to manage its lifetime. 如果需要关闭连接,则应使用using()块来限制上下文的范围,直到您能够实现IoC容器来管理其生存期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM