2012-03-07 16 views
0

我从网上数据使用类似于循环填充我的数据库(简化,没有错误检查)的想法:EF 4.1寻求如何加快加入行

foreach (var catalog in catalogs) 
{ 
    var result = Items(catalog, state, context); 
    while (result != null) 
    { 
     result.ForEach(r => context.DbContext.Items.Add(r)); 
     context.DbContext.SaveChanges(); 
     result = Items(catalog, state, context); 
    } 
}     

代码需要一些时间来获得XML来自服务器的响应并使用响应流上的XElement.Load将其解码为XElement。它被解码为包含最多50项的项目列表 - 这是我在每次循环传递中从服务器请求的内容。由于SaveChanges调用,该块会立即保存到表格中。

将循环时间的8/10花费在将项目添加到DbContext或SaveChanges调用上或两者上。与远程服务器进行通信并将响应XML解码为实体列表为2/10。

如何提高将数据存储到数据库的效率,同时仍然与EF保持同步?

我知道我可以从XML批量加载数据库,但是这会迫使我找出需要编写的SQL语句,因为几个相关的表使用上面的SaveChanges调用进行更新,因此我启动失去了使用EF的优势。

回答

2

简而言之:您无法使用纯EF加速您的插入过程,因为EF有very poor performance for bulk/batch data processing。您有两个问题:

  • 将实体添加到上下文中会产生一些成本,并且随着上下文中已经存在的每个实体都会增加成本。为避免这种情况,您可以在每次致电Add后尝试拨打SavaChanges,甚至尝试为每批次或甚至每次拨打Add使用新的上下文。
  • EF为每个要插入,更新或删除的记录都进行一次单独的数据库往返,因此通常不需要多久拨打SaveChanges。避免这种情况大多只有在使用直接SQL并创建一个执行所有插入操作的单个时才是可能的。

如果要提高性能,请使用直接SQL。

+0

叹息。最初我期望从流构造XElement,然后从其XElement子项创建POCO对象列表将是瓶颈! – Tony 2012-03-07 15:41:18