[英]Fastest way to update all rows to have same value in one column in datatable, without loop in C#
I have datatable "users" and column "is_published" in it. 我有数据表“users”和列“is_published”。 I have about 100k rows.
我有大约100k行。 What is the fastest way to update value in the column, so the whole rows in column have same value = 1.
更新列中值的最快方法是什么,因此列中的整行具有相同的值= 1。
I try with classic foreach loop and it't slow, also I try with LINQ : 我尝试使用经典的foreach循环而且速度不慢,我也尝试使用LINQ:
dsData.Tables["users"].Select().ToList().ForEach(x => x["is_published"] = 1;);
and it still isn't fast enough. 它仍然不够快。
Also variant wit Expression doesn't work for me, because after that fields is ReadOnly and I can't change value again. 另外变体机智表达式对我不起作用,因为在该字段之后是ReadOnly并且我不能再次更改值。
This is C#. 这是C#。
when you create your table you can simply push a default value to your column.. 创建表时,只需将默认值推送到列中即可。
DataTable dt = new DataTable();
dt.Columns["is_published"].DataType = System.Int32;
dt.Columns["is_Published"].DefaultValue = 1;
then when you need to change the rows to default value ( or will you need? ) 然后当你需要将行更改为默认值(或者你需要?)
// Say your user selects the row which its index is 2..
// The ItemArray gives the selectedRow's cells as object..
// And say your columns index no is 5..
dt.Rows[2].ItemArray[5] = default ;
or 要么
dt.Rows[2].ItemArray[5] = dt.Columns["is_published"].DefaultValue;
Separate the select and the update into two operations. 将选择和更新分成两个操作。 Skip the
ToList()
operation and instead iterate afterwards over the IEnumerable
collection using forEach
and update the value: 跳过
ToList()
操作,然后使用forEach
在IEnumerable
集合上迭代并更新值:
var rows = dsData.Tables["users"].Select();
forEach(var row in rows)
{
row["is_published"] = 1;
}
The ToList
forces an immediate query evaluation which in this case acts as a copy of all items from the IEnumerable
collection, so you can gain some speed here. ToList
强制立即进行查询评估 ,在这种情况下,它作为IEnumerable
集合中所有项目的副本,因此您可以在这里获得一些速度。 I ran some tests and the result in this case is (using your code and the modification): ToList
is 3 times slower than iterating over IEnumerable
and single update! 我运行了一些测试,在这种情况下的结果是(使用你的代码和修改):
ToList
比迭代IEnumerable
和单个更新慢3倍 !
IMO 40 seconds is an awful lot for 100K items. 对于100K物品,IMO 40秒非常多。 If your
DataTable
is bound to a DataGridView
or some other UI control, i believe that the update of the GUI is taking so long and not the update of the values itself. 如果您的
DataTable
绑定到DataGridView
或其他一些UI控件,我相信GUI的更新需要很长时间,而不是更新值本身。 In my tests the update using ToList
took fractions of a second (on my simple Lenovo netbook with AMD E-450 processor, and i assume you are not using a 386 machine). 在我的测试中,使用
ToList
的更新花了不到一秒钟(在我的简单联想上网本上使用AMD E-450处理器,我假设你没有使用386机器)。 Try suspending the UI bevor updating and refreshing the values and then enable it again - example in this SO post . 尝试暂停UI bevor更新并刷新值,然后再次启用它 - 例如在此SO帖子中 。
My original post (as i can see you gained some speed using the code - interesting): 我的原帖(因为我可以看到你使用代码获得了一些速度 - 有趣):
More an experiment for my part, but it is possible to: 对我来说更多的实验,但有可能:
The code: 编码:
// temp table
var dataTable = new DataTable("Table 1");
dataTable.Columns.Add("title", typeof(string));
dataTable.Columns.Add("number", typeof(int));
dataTable.Columns.Add("subnum1", typeof(int));
dataTable.Columns.Add("subnum2", typeof(int));
// add temp data
Enumerable.Range(1, 100000).ToList().ForEach(e =>
{
dataTable.Rows.Add(new object[] { "A", 1, 2, 3 });
});
// "bulk update"!
var sb = new StringBuilder();
var xmlWriter = XmlWriter.Create(sb);
dataTable.WriteXml(xmlWriter);
var xml = XDocument.Parse(sb.ToString());
// take column to change
var elementsToChange = xml.Descendants("title").ToList();
// the list is referenced to the XML, so the XML is changed too!
elementsToChange.ForEach(e => e.Value = "Z");
// clear current table
dataTable.Clear();
// write changed data back to table
dataTable.ReadXml(xml.CreateReader());
The table is updated. 该表已更新。 IMO the parts that make this solution slow are the
IMO使这个解决方案变慢的部分是
The other way around the pure update of the list is probably faster than the table update. 纯粹更新列表的另一种方法可能比表更新更快。
Finaly! Finaly! I speed up update so it takes 2-3 sec.
我加快更新速度,所以需要2-3秒。 I added BeginLoadData() and EndLoadData()
我添加了BeginLoadData()和EndLoadData()
DataTable dt = ToDataSet().Tables["users"];
var sb = new StringBuilder();
var xmlWriter = XmlWriter.Create(sb);
dt.WriteXml(xmlWriter);
var xml = XDocument.Parse(sb.ToString());
xml.Descendants("is_published").ToList().ForEach(e => e.Value = "1");
dt.Clear();
dt.BeginLoadData();
dt.ReadXml(xml.CreateReader());
dt.EndLoadData();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.