此代码有效,但是花费太多时间。每个数据表都包含1000行,每次我需要针对某个列从另一个数据表中过滤数据。
for (int i = 0; i < dsResult.Tables[0].Rows.Count; i++)
{
DataTable dtFiltered = dtWorkExp.Clone();
foreach (DataRow drr in dtWorkExp.Rows)
{
if (drr["UserId"].ToString() == dsResult.Tables[0].Rows[i]["Registration NO."].ToString())
{
dtFiltered.ImportRow(drr);
}
}
DataTable dtFilteredAward= dtAwards.Clone();
foreach (DataRow drr in dtAwards.Rows)
{
if (drr["UserId"].ToString() == dsResult.Tables[0].Rows[i]["Registration NO."].ToString())
{
dtFilteredAward.ImportRow(drr);
}
}
DataTable dtFilteredOtherQual = dtOtherQual.Clone();
foreach (DataRow drr in dtOtherQual.Rows)
{
if (drr["UserId"].ToString() == dsResult.Tables[0].Rows[i]["Registration NO."].ToString())
{
dtFilteredOtherQual.ImportRow(drr);
}
}
//Do some operation with filtered Data Tables
}
答案 0 :(得分:1)
您可以在for循环之外声明这些行。
DataTable dtFiltered = dtWorkExp.Clone();
您可以将其分配给一个变量并使用它,而不必每次都访问dsResult.Table [0]。
您也可以用LINQ替换foreach循环。
答案 1 :(得分:1)
将表达式的值放在变量中。
var regNo = dsResult.Tables[0].Rows[i]["Registration NO."].ToString();
将列的索引放入变量。通过索引访问要比通过列名访问更快。
int index = dtWorkExp.Columns["UserId"].Ordinal;
结果代码:
int dtWorkIndex = dtWorkExp.Columns["UserId"].Ordinal;
int dtAwardsIndex = dtAwards.Columns["UserId"].Ordinal;
int dtOtherQualIdex = dtOtherQual.Columns["UserId"].Ordinal;
for (int i = 0; i < dsResult.Tables[0].Rows.Count; i++)
{
var regNo = dsResult.Tables[0].Rows[i]["Registration NO."].ToString();
DataTable dtFiltered = dtWorkExp.Clone();
foreach (DataRow drr in dtWorkExp.Rows)
{
if (drr[dtWorkIndex].ToString() == regNo)
{
dtFiltered.ImportRow(drr);
}
}
...
当然,如果您确切地知道列索引,则可以将其设置为常量。另外,如果UserId索引在所有表中都匹配,则单个变量就足够了。
您也可以尝试使用BeginLoadData和EndLoadData方法。
DataTable dtFiltered = dtWorkExp.Clone();
dtFiltered.BeginLoadData();
foreach (DataRow drr in dtWorkExp.Rows)
{
if (drr[dtWorkIndex].ToString() == regNo)
{
dtFiltered.ImportRow(drr);
}
}
dtFiltered.EndLoadData();
但是我不确定它们是否与ImportRow
一起使用。
最后,并行化会有所帮助。
for (int i = 0; i < dsResult.Tables[0].Rows.Count; i++)
{
var regNo = ...;
var workTask = Task.Run(() =>
{
DataTable dtFiltered = dtWorkExp.Clone();
foreach (DataRow drr in dtWorkExp.Rows)
{
if (drr[dtWorkIndex].ToString() == regNo)
{
dtFiltered.ImportRow(drr);
}
}
return dtFiltered;
});
var awardTask = Task.Run(() =>
...
var otherQualTask = Task.Run(() =>
...
//Task.WaitAll(workTask, awardTask, otherQualTask);
await Task.WhenAll(workTask, awardTask, otherQualTask);
//Do some operation with filtered Data Tables
}
答案 2 :(得分:1)
我会做什么:
可枚举的主数据表的所有行:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bgMain">
<androidx.appcompat.widget.Toolbar
android:id="@+id/RecordToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextAppearance="@style/toolbarTextSize"
app:title="Record"
android:theme="@style/RecordActionBar"
android:background="@color/toolbar"
app:titleMarginStart="20dp"
app:titleTextColor="@color/white"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerViewRecord"
android:layout_below="@+id/RecordToolbar"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigationBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:padding="0dp"
app:itemBackground="@color/toolbar"
app:itemIconTint="@drawable/selector"
app:itemTextColor="@drawable/selector"
app:menu="@menu/bottom_nav" />
</RelativeLayout>
获取您要用于过滤的列:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bgMain"
>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/RecordToolbar"
android:elevation="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"
android:padding="10dp"
>
<TextView
android:id="@+id/recordTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:layout_marginBottom="5dp"
android:textColor="@color/white"
android:textSize="25sp" />
<ImageButton
android:id="@+id/recordDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@color/colorPrimaryDark"
android:padding="0dp"
android:src="@drawable/ic_delete"
/>
<TextView
android:id="@+id/recordCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordTitle"
android:text="Count: 44"
android:textColor="@color/white" />
<TextView
android:id="@+id/recordLap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordTitle"
android:layout_marginStart="10dp"
android:layout_toRightOf="@+id/recordCount"
android:text="Lap: 8"
android:textColor="@color/white" />
<TextView
android:id="@+id/recordLimit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordTitle"
android:layout_marginStart="10dp"
android:layout_toRightOf="@+id/recordLap"
android:text="Limit: 66"
android:textColor="@color/white" />
<TextView
android:id="@+id/recordTotalCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordTitle"
android:layout_marginStart="10dp"
android:layout_toRightOf="@+id/recordLimit"
android:text="Total Count: 572"
android:textColor="@color/white" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
创建一个接受该过滤器的方法,一个要过滤的表和一个要比较的字段。
var rows = dsResult.Tables[0].AsEnumerable();
最后使用该方法过滤所有表:
var filter = rows.Select(r => r.Field<string>("Registration NO."));
总会是这样
public static DataTable Filter<T>(EnumerableRowCollection<T> filter, DataTable table, string fieldName)
{
return table.AsEnumerable().Where(r => filter.Contains(r.Field<T>(fieldName))).CopyToDataTable();
}