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

时间:2013-10-30 07:35:36

标签: c# asp.net-mvc linq entity-framework entity-framework-4

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

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

我在存储库中有以下两种方法

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

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

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

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

2 个答案:

答案 0 :(得分: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");
}

然后,您可以添加特定过滤器,并ToList更小的结果。 e.g。

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
}

希望这有帮助

答案 1 :(得分:0)

AS Parallel(),不使用Linq to Entities,只使用Linq to Object。

用EF装载200K不是很好。

您可以通过只读加载来提高性能:

context.POINTS_TABLE.MergeOption = MergeOption.NoTracking;