2012-07-18 42 views
4

我在我的ASP.NET Web服务项目中有一个数据表,这个数据表有大约500K条记录,它有39列,存在于缓存中。 一分钟后在后台线程访问数据库,汇集了来自数据库的更新记录,我想在缓存数据表进行更新,我使用下面的方法,但它正在好足够的时间来做到这一点:从另一个数据表更新数据表中的数据的有效方法

foreach (DataRow dRNew in dtNew.Rows) 
{ 
    DataRow row = dtOriginal.Select("ID=" + dRNew["ID"]).First(); 
    row["Column1"] = dRNew["Column1"]; 
    row["Column2"] = dRNew["Column2"]; 
    row["Column3"] = dRNew["Column3"]; 
} 

我已经取代了以下行:

DataRow row = dtOriginal.Select("ID=" + dRNew["ID"]).First(); 

DataRow row = dtOriginal.AsEnumerable().Where(r => ((Int64)r["ID"]).Equals(dRNew["ID"])).First(); 

但不成功,它正在像我的笔记本电脑约5分钟。

任何人都可以请指导我在哪里,我做错了什么?使用哪种方法可以有效地进行,我不确定是否可以使用Dataset.Merge或其他方法。

+4

SCNR ...'[...]数据表[...] 500K记录它与39列存在于Cache中“让我立即笑了起来......数据表+缓存+ foreach +多线程+ ...... **血腥真棒**!你一定是查克·诺里斯... – 2012-07-18 12:44:12

+0

:)可能对你很有趣,但在我的情况下,它是这样的,所以让我们一起笑吧:D – 2012-07-18 12:47:10

+2

其实我笑,因为env你正在追捕_really_伤害......在这种情况下,没有一种高性能/实用的解决方案。我宁愿从一个基本问题开始:为什么你必须将值存储在某个地方?你在做什么?给我们一个更大的图片! ... – 2012-07-18 12:49:13

回答

1

,您可以尝试这样

dtOriginal.Merge(dtNew); 
+0

为什么采取副本,而不是只dtOriginal.Merge(dtNew)? – 2012-07-18 14:02:54

+0

@MAfifi对不起,我只是举了一个快速的例子,你已经可以使用这些方法来实现它了,请使用适合你的代码 – HatSoft 2012-07-18 14:09:24

+0

@MAfifi我已经更新了安装程序 – HatSoft 2012-07-18 14:10:25

0

试试这个方法,DataRowCollection.Find。假设你的DataTable设置正确,它将是O(log(n))而不是它当前的O(N)。

foreach (DataRow dRNew in dtNew.Rows) 
{ 
    DataRow row = null; 
    try 
    { 
     row = dtOriginal.Find(dRNew["ID"]); 
    } 
    catch (MissingPrimaryKeyException) 
    { 
     row = dtOriginal.Select("ID=" + dRNew["ID"]).First(); 
    } 
    if (row != null) 
    { 
     row["Column1"] = dRNew["Column1"]; 
     row["Column2"] = dRNew["Column2"]; 
     row["Column3"] = dRNew["Column3"]; 
    } 
} 
+0

请......不要忘记外层的'foreach'。也许宁可加入数据集? – 2012-07-18 13:19:21

+0

这基本上就是Merge所做的。 – 2012-07-18 14:01:59

+0

是的,没有......应该只有39列中的3更新 - 所以本质上不是_real_合并 – 2012-07-18 14:09:51

1

我会想到用这将是更快:

TableToUpdate.AsEnumerable().Join 
(
    TableToUpdateFrom.AsEnumerable(), 
    lMaster => lMaster["COMMON_FIELD"], lChild => lChild["COMMON_FIELD"], 
    (lMaster, lChild) => new { lMaster, lChild } 
    ).ToList().ForEach 
(
o => 
{ 
    o.lMaster.SetField("FIELD_TO_BE_UPDATED1", o.lChild["FIELD_TO_BE_UPDATED_FROM1"].ToString()); 
    o.lMaster.SetField("FIELD_TO_BE_UPDATED2", o.lChild["FIELD_TO_BE_UPDATED_FROM2"].ToString()); 
    o.lMaster.SetField("FIELD_TO_BE_UPDATED3", o.lChild["FIELD_TO_BE_UPDATED_FROM3"].ToString()); 
    o.lMaster.SetField("FIELD_TO_BE_UPDATED_ETC", o.lChild["APPROVAL_SCORE_FROM_ETC"].ToString()); 
} 
); 
+0

HI Naelem,你能告诉我如何在这个LINQ中给出两个条件......在上面的代码中,如何添加另一个公共字段? – Madhu 2015-12-31 04:04:34

相关问题