我有两个数据表。 DataTable dtRequired和DataTable dtResult。
我想输出一个数据表,其中包含dtResponse中不存在但在dtRequired中找到的行。
方法1 我们一直在使用以下网址http://weblogs.sqlteam.com/davidm/archive/2004/01/19/739.aspx中指定的算法。 这个算法在我们的分析中被认为是较慢的算法之一。
方法2 所以,我试图用下面描述的东西替换上面的算法。 dtRequired在我使用下面的列上编入索引,以查找行。
if (dtResult.Rows.Count > 0)
{
lock (dtResult)
{
DataRow rowfound = null;
for (int i = 0; i < dtResult.Rows.Count; i++)
{
DataRow row = dtResult.Rows[i];
rowfound = dtRequired.Rows.Find(new object[] { row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8] });
if (rowfound != null)
{
dtRequired.Rows.Remove(rowfound);
}
}
}
}
然而,上述部分花费的时间比方法1 所花费的时间更长。 方法2 对于1250行的dtResult需要约3秒,而需要4500行需要dtRequired。
我上面提到的方法有问题吗?有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
这是MSDN页面的link,它使用LINQ to DataSet来获取两个数据表中出现的行。此示例使用 Intersect 。我认为您可以使用来修改它,而不是。我不知道表现是否会更好。
答案 1 :(得分:0)
private IEnumerator<object[]> GetEnumerator( DataTable dtRequired, DataTable dtResponse )
{
foreach( DataRow row in dtResponse.Rows )
{
// use the columns of the primary key below
if( dtResult.Rows.Contains( new object[] { row[0], row[2], row[4] } ) )
continue;
else
yield return row.ItemArray;
}
}
private void GetComplement( DataTable dtRequired, DataTable dtResponse, out DataTable dtResult )
{
DataTable dtResult = dtRequired.Clone();
foreach( object[] items in GetEnumerator( dtRequired, dtResponse ) )
{
dtResult.Rows.Add( items );
}
return;
}
答案 2 :(得分:0)
你说你的循环Find()方法效率低于方法1 http://weblogs.sqlteam.com/davidm/archive/2004/01/19/739.aspx。
我见过人们谈论ADO.NET 3.5和LINQ,假设你有一个生产LINQ或使用迭代方法来填充一些通用容器。
我想知道HashTable的创造性使用是否恰好更快,更具计算性(现实世界,不是理论)。在Diff(tbl1,tb2)的情况下,只需用tbl2填充哈希值,然后迭代地添加tbl1成员。对于每次成功,还要将成员的副本添加到要显示/返回的输出(差异)数组中。显然,对于每个失败,它已经存在,所以不要输出/返回该值。
请告诉我,如果您确认3是最快的,我会修改我的代码。我想将DirectoryServices.FindAll()Collection与SqlDataReader()进行比较,而LINQ to Active Directory则在第三方Beta中。所以我需要一个'生产'批准的方法,尽可能高效地@ 15,000个对象。