如何加速IEnumerable <t>数据库访问

时间:2015-08-19 10:42:14

标签: linq ienumerable tolist

我首先使用EF6代码执行查询,该查询为并行GPU处理提取大量数据。 linq查询返回IEnumerable。

IEnumerable<DatabaseObject> results = ( from items in _myContext.DbSet
                           select items).Include("Table1").Include("Table2");

现在,我需要对整套数据进行一些统计分析,并将结果呈现给用户。

不幸的是,由于返回数据的庞大规模,只是做了一个 results.ToList()需要很长时间才能完成......我甚至还没有开始对数据进行并行处理!

除了减少数据量之外,我还能做些什么来提高效率?这不是一个选项,因为它是需要处理的完整数据集。

编辑1

我目前的代码首先如下:

public class Orders
{
    [Key]
    public virtual DateTime ServerTimeId
    {
        get;
        set;
    }

    public string Seller
    {
        get;
        set;
    }


    public decimal Price
    {
        get;
        set;
    }


    public decimal Volume
    {
        get;
        set;
    }

    public List<Table1> Tables1{ get; set; }


    public List<Table2> Table22{ get; set; }
}

虽然不使用.Include我的查询显着加快,如果我不使用.Include(“Tables1”.Include(“Tables2”)这些字段为null 在此查询的最终结果中:

var result = ( from items in _context.DbOrders
                       select orderbook ).Include("Tables1").Include("Tables2")

在我的DbContext中,我定义了:

public DbSet<Orderok> DbOrders { get; set; }

如果有办法强制EF6在不使用.Include的情况下填充这些表格,那么如果有人能指导我,我会很高兴。

1 个答案:

答案 0 :(得分:0)

您可以将主表DbOrders和子表分别加载到上下文中:

_myContext.Configuration.ProxyCreationEnabled = false;

_myContext.DbOrders.Load();
_myContext.Table1.Load();
_myContext.Table2.Load();

现在,上下文完全按照您需要的数据收费。我希望你不会遇到内存不足的异常(因为整个方法崩溃了)。

实体框架优先于关系修正,这意味着它会填充导航属性DbOrders.Table1DbOrders.Table1

禁用代理创建有两个原因:

  • 物化对象尽可能轻量化
  • 禁用延迟加载,否则在访问导航属性时会触发。

现在,您可以通过访问Local集合继续使用数据:

from entity in _myContext.DbOrders.Local
...

您可以通过取消映射您不需要的所有数据库字段来进一步尝试加速该过程。这使得SQL结果集更小,物化对象将更轻。要实现这一点,也许你必须创建一个专用的上下文。