我有这个DataTable
FName LName Tag1 Tag2 Tag3 ... (not fixed, can be as many)
我想要的是
FName LName TagAll
string
的列TagAll
,表达式为
var expression = string.Empty;
// ... other code
// In a loop for all tag columns
expression = expression + " + ',' + " + tagColumn;
// at the end of loop
dtContact.Columns["Tag_All"].Expression = expression;
如果我有3列,表达式是这样的
"Tag1 + ',' + Tag2 + ',' + Tag3"
例如数据为
FName LName Tag1 Tag2 Tag3
Jeff Atwood test tag other
Matt breeden myTag total last
结果DataTable
变成如下所示
FName LName Tag1 Tag2 Tag3 Tag_All
Jeff Atwood test tag other test, tag, other
Matt breeden myTag total last myTag, total, last
它很好,直到现在,但现在我想删除所有这些其他Tag(s)
列。我试着做
dtContact.Columns.RemoveAt(2)
但是会抛出'System.ArgumentException'
我猜这是因为该列在计算列表达式中使用,是正确的吗?因为当我移除第0列或第1列。它工作得很好。那么,有没有一种方法,我可以删除所有这些其他Tag(s)
列,给他们在计算列表达式中使用?也许能让这个专栏持久存在?虽然我在谷歌上搜索了一下,但没有找到任何东西。
此外,就像我说的,这是不固定的,只有2,或3或n个这些Tag(s)
列,它们是动态的,可以只有1,Tag1
,最多任何…比如Tag88
之类的
试试这个方法:
//Usage
DataTable dtMod = GetModifiedTable( dt);
//Function to return modified data table
public DataTable GetModifiedTable(DataTable dt)
{
var columnList = dt.Columns.Cast<DataColumn>()
.Where(x => x.ColumnName.StartsWith("Tag"))
.Select(x => x.ColumnName)
.ToArray();
DataTable dtNew = new DataTable();
dtNew.Columns.Add("FName");
dtNew.Columns.Add("LName");
dtNew.Columns.Add("Tag_All");
var results = dt.AsEnumerable().Select(r =>
dtNew.LoadDataRow(
new object[] {
r.Field<string>("FName"),
r.Field<string>("LName"),
GetTagValues(r, columnList)
}, false
));
dtNew.Rows.Add(results.ToArray());
return dtNew;
}
//Function to return csv values of given column list
public string GetTagValues(DataRow r, string[] columns )
{
string csv = string.Empty;
foreach(string column in columns)
{
csv += r[column].ToString() + ",";
}
return csv.Substring(0, csv.Length - 1);
}
你不能这么做。你必须采取另一种方法。
添加TAG_ALL列,但不作为计算列。对于DataTable中的每一行,遍历所有TagX列并将它们相加,然后将值分配给Tag_All列。对每一行重复。完成后,现在可以删除TagX列。
根据行数的不同,这实际上可以非常快。
然而,我怀疑这是否是个好主意。如果要将DataTable绑定到某个网格,那么所需要做的就是不绑定TagX列,或者告诉grid使这些列不可见。
在处理数据表内的大量数据(大约500000行)时,遍历行需要花费时间(即使使用dt.AsEnumerable().Select()
方法)。我正在寻找一个更快的方法,直到我发现以下解决方案:
- 将数据表(仅结构)克隆到新表
- 遍历列并删除表达式(设置为"),或者仅删除特定
Datacolumn
的表达式 - 合并新数据表和旧数据表。
现在可以在不影响计算列的情况下删除原始列。
例子:
//assign expression
var expression = string.Empty;
expression = expression + " + ',' + " + tagColumn;
dtContact.Columns["Tag_All"].Expression = expression;
//Clone datatable structure
DataTable dtNew = dtContact.Clone();
//Remove expression from a specific column
dtNew.Columns["Tag_All"].Expression = "";
//Merge data with the new Table
dtNew.Merge(dtContact);
dtContact.Dispose();
//Now you can remove the column used within the expression
dtNew.Columns.RemoveAt(2);
查看下面的代码:
private void creatable()
{
dt.Columns.Add("FName");
dt.Columns.Add("LName");
dt.Columns.Add("Tag1");
dt.Columns.Add("Tag2");
dt.Columns.Add("Tag3");
dt.Columns.Add("Tag_All");
}
private void removeColumn()
{
string temp = null;
List<string> colToRemove = new List<string>();
int colcount = dt.Columns.Count;
for (int i = 0; i <colcount ;i++ )
{
temp = dt.Columns[i].ColumnName;
if (temp == "Tag1" || temp == "Tag2" || temp == "Tag3")
{
colToRemove.Add(temp);
}
temp = null;
}
foreach (string item in colToRemove)
{
dt.Columns.Remove(item);
}
}
正在按你的要求工作