我正在处理2个数据表:
- SSFE:包含我要查找的值
- FFE:大于、小于或等于SSFE,但不一定包含SSFE的每个值
我需要在这些表之间匹配的值是整数,两个表都是从小到大排序的。我的想法是开始搜索FFE中的第一个项目,开始在SSFE中循环,当我找到匹配项时->记住当前索引->保存匹配项->从FFE中选择下一个项目并从上一个索引继续。
此外,FFE可以包含整数,但也可以包含字符串,这就是为什么我将值强制转换为字符串并进行比较。
我做了一些代码,但花了太多时间。将SSFE(1.000个项目)与FFE(127.000个)项目进行比较大约需要一分钟时间。
int whereami = 0;
bool firstiteration = true;
for (int i = 0; i < FFEData.Rows.Count - 1; i++)
{
for (int j = 0; j < SSFEData.Rows.Count - 1; j++)
{
if (firstiteration)
{
j = whereami;
firstiteration = false;
}
if (SSFEData.Rows[j][0] == FFEData.Rows[i][0].ToString())
{
found++;
whereami = j;
firstiteration = true;
break;
}
}
}
我只存储我发现的发生次数以供测试。在这个例子中,它将找到490个匹配,而不是说这是相关的。
任何建议都很好!
可以尝试DataRelation类。它在数据集中的两个数据表之间创建外键/联接。
using System.Data;
using System.Text;
public int GetMatches(DataTable table1, DataTable table2)
{
DataSet set = new DataSet();
//wrap the tables in a DataSet.
set.Tables.Add(table1);
set.Tables.Add(table2);
//Creates a ForeignKey like Join between two tables.
//Table1 will be the parent. Table2 will be the child.
DataRelation relation = new DataRelation("IdJoin", table1.Columns[0], table2.Columns[0], false);
//Have the DataSet perform the join.
set.Relations.Add(relation);
int found = 0;
//Loop through table1 without using LINQ.
for(int i = 0; i < table1.Rows.Count; i++)
{
//If any rows in Table2 have the same Id as the current row in Table1
if (table1.Rows[i].GetChildRows(relation).Length > 0)
{
//Add a counter
found++;
//For debugging, proof of match:
//Get the id's that matched.
string id1 = table1.Rows[i][0].ToString();
string id2 = table1.Rows[i].GetChildRows(relation)[0][0].ToString();
}
}
return found;
}
我用nvarchar(2)字符串随机填充了两个非索引表,每个表有10000行。这场比赛用了不到1秒的时间,包括填写表格所花费的时间。我平均一次能得到3500到4000场比赛。
然而,主要的警告是,匹配的DataColumns必须为相同的数据类型。所以,如果这两列都是字符串,或者至少是以字符串形式存储的整数,那么这将起作用。
但是,如果一列是整数,则必须添加一个新列,并首先将整数作为字符串存储在该列中。字符串翻译将增加大量时间。
另一种选择是将表上传到数据库并执行查询。这么大的上传可能需要几秒钟,但查询也不到一秒钟。所以仍然比60秒以上要好。