我有DataTable
FName LName Tag1 Tag2 Tag3 ... (not fixed, can be as many)
我想要的是
FName LName TagAll
因此,我创建了一个类型为TagAll
的列string
,其表达式为
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)
列,因为它们用在计算列表达式中?可能以某种方式使这个列持久化?虽然我在Google上搜索过它但却找不到任何东西。
另外,就像我说的那样,并不是固定的,这些Tag(s)
列只有2个,3个或n个,它们是动态的,只有1个,Tag1
,最多...说Tag88
或其他什么。
答案 0 :(得分:2)
试试这个方法:
//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);
}
答案 1 :(得分:1)
你不能这样做。你必须采取另一种方法。
添加TAG_ALL列,但不是计算列。对于DataTable中的每一行,请浏览所有添加它们的TagX列,然后将值分配给Tag_All列。每行重复一次。完成后,您现在可以删除TagX列。
根据行数,这实际上可能非常快。
但是,我怀疑这是不是一个好主意。如果要将DataTable数据绑定到某个网格,那么您需要做的就是不绑定TagX列,或者告诉Grid使这些列不可见。
答案 2 :(得分:0)
在处理数据表(约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);
答案 3 :(得分:-1)
查看此代码:
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);
}
}
它符合您的要求。