为什么实体框架.ToList()与.Include非常慢,我怎样才能加快速度?

Don*_*nQi 3 c# linq asp.net-mvc entity-framework entity-framework-4

我正在使用EF4查询oracle数据库.

我有2个表POINTS(大约100 000行)COUNTRIES,每个点都有一个countryCode外键

我在存储库中有以下2个方法

public List<PointsTable> GetAll()
{
    using (Entities context = new Entities())
    {
        List<PointsTable> theList = context.POINTS_TABLE.ToList();
        return theList;
    }
}

public List<PointsTable> GetAllComplete()
{
    using (Entities context = new Entities())
    {
        List<PointsTable> theList = context.POINTS_TABLE.Include("Countries").ToList();
        return theList;
    }
}
Run Code Online (Sandbox Code Playgroud)

GetAll需要5秒,但在GetAllComplete需要2分钟!

我使用AsParallel()但收益很荒谬.

我可以加快速度,或者是什么导致它变慢?

Nin*_*Nye 5

原因是,对于每条记录,您要检索的是200k记录的国家,这些记录会增加到很多记录中.

您是否要稍后查询此数据以将其降低到您的特定需求?如果是这样,.ToList()他们还没有.

更改您的存储库方法以返回IQueryable,这样您就可以将查询限制为稍后需要的特定数据,从而减少您放入记忆中的数据量

private Entities _context;

public PointsRepository(Entities context)
{
    _context = context
}

public IQueryable<PointsTable> GetAll()
{
    return context.POINTS_TABLE;
}

public IQueryable<PointsTable> GetAllComplete()
{
    return context.POINTS_TABLE.Include("Countries");
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以添加特定的过滤器和ToList较小的结果.例如

using (Entities context = new Entities())
{
    var rep = new PointsRepository(context);

    // This will change the query you send to sql to only 
    // retrieve the specific data you want and should result 
    // in much quicker execution
    var result = rep.GetAllComplete()                    // get all with includes
                    .Where(p => p.Property = "Specific") // refine the query 
                    .ToList()                            // retrieve the data and add to memory
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助