2011-08-19 24 views
3

我有我的模型根据字典形式进来的一些信息更新数据库。我现在做的方式是如下:数据库更新字典/列表速度

SortedItems = db.SortedItems.ToList(); 
foreach (SortedItem si in SortedItems) 
{ 
    string key = si.PK1 + si.PK2 + si.PK3 + si.PK4; 
    if (updates.ContainsKey(key) && updatas[key] != si.SortRank) 
    { 
     si.SortRank = updates[key]; 
     db.SortedItems.ApplyCurrentValues(si); 
    } 
} 
db.SaveChanges(); 

难道是更快的通过字典迭代,并为每个项目做一个数据库查询?字典只包含已更改的项目,并且可以是从2项目到整个集合的任何地方。我对替代方法的想法是:

foreach(KeyValuePair<string, int?> kvp in updates) 
{ 
    SortedItem si = db.SortedItems.Single(s => (s.PK1 + s.PK2 + s.PK3 + s.PK4).Equals(kvp.Key)); 
    si.SortRank = kvp.Value; 
    db.SortedItems.ApplyCurrentValues(si); 
} 
db.SaveChanges(); 

编辑:假设更新的数量通常是DB的约5-20%entires

+1

要记住的主要事情是,您的数据库调用的可能性比字典查找要慢。因此,如果可能的话,您想尽量减少数据库交互(作为一般经验)。 –

回答

4

让我们来看看:

方法1 :

  • 你会从所有的1000个项目在数据库中迭代
  • 您仍然可以访问词典中的每一项,并且有950次错过字典
  • 您仍然有50次更新对数据库的调用。

方法2:

  • 你会遍历字典中的
  • 你必须50个人查找调用数据库中没有遗漏字典的每个项目。
  • 您将有50个更新对数据库的调用。

这实际上取决于数据集有多大以及平均得到修改的百分比。

你也可以做这样的事情:

方法3:

  • 建立一个集中的所有键从字典
  • 查询数据库一次匹配这些键的所有项目
  • 迭代结果并更新每个项目

就我个人而言,我会尝试确定您的典型案例场景并分析每个解决方案以查看哪个最佳。不过,我认为第二种解决方案,如果你有大量的更新和大量的更新,将会产生大量的数据库和网络点击量,因为对于每次更新,它都必须打两次数据库(一次获得项目,一次更新该项目)。

所以,是的,这是一个很长篇大论说的方式“这取决于......”

如果有疑问,我会编写既和他们基于的生产场景复制品时间。

0

要添加到@James'答案,您将使用存储过程(或常规SQL命令)获得最快的结果。

的问题LINQ到实体(和其他LINQ提供者,如果他们没有最近更新的)是,他们不知道如何生产与where子句SQL更新:

update SortedItems set SortRank = @NewRank where PK1 = @PK1 and (etc.) 

一存储过程会在服务器端执行此操作,而您只需要一个db调用。