4
DataTable dtt = (DataTable)Session["ByBrand"];
var filldt = (dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "")).CopyToDataTable();

このコードは、選択した DataTable で値が見つかった場合は正常に動作しますが、DataTable で値が見つからない場合はエラーが表示されます。レコードが見つからないかどうかを確認する方法を教えてください。

4

2 に答える 2

6

Selectが何かを返すかどうかを確認するだけですか?

 DataTable dtt = (DataTable)Session["ByBrand"];
 DataRow[] rows = dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "");
if(rows.Length > 0)
{
    var filldt = rows.CopyToDataTable();
}

さて、ティムのLinqの例は本当に素晴らしいですが、私の答えを完成させるために。Select メソッドは、行が選択されていない場合も常に DataRow 配列を返しますが、この空の配列からデータテーブルを構築するように要求することはできません。考えてみてください。配列に行が存在しない場合、CopyToDataTable は結果のテーブルに対してどのスキーマを構築する必要がありますか?

于 2013-06-03T10:23:01.763 に答える
6

Linqにタグを付けましたがDataTable.Select、古い方法でフィルター処理を行っていDataTableます。Enumerable.WhereストロンジルタイプのField伸張方法を使用。

decimal priceFrom = decimal.Parse(HiddenField1.Value);
decimal priceTo = decimal.Parse(HiddenField2.Value);

var dtFiltered = dtt.AsEnumerable()
    .Where(row => row.Field<decimal>("Price") >= priceFrom 
               && row.Field<decimal>("Price") <= priceTo))
    .CopyToDataTable();

列のタイプが であると仮定するとdecimal、別のタイプの場合は、それを使用するFieldか、最初に変換する必要があります。

System.Linq(ファイル) とSystem.Data.DataSetExtensions(プロジェクト)への参照を追加する必要があることに注意してください。

アップデート

ただし、値がDataTableに見つからない場合はエラーが表示されます

CopyToDataTable入力シーケンスが空の場合、例外をスローします。私の意見では、最善のアプローチは、そのケースを個別に処理することです。

DataTable tblFiltered = dtt.Clone(); // clones only structure not data
var filteredRows = dtt.AsEnumerable()
    .Where(row => row.Field<decimal>("Price") >= priceFrom 
               && row.Field<decimal>("Price") <= priceTo));
if(filteredRows.Any())
{
    tblFiltered = filteredRows.CopyToDataTable();
}

Anyまたは、このアプローチは、最悪の場合に追加の完全な列挙を引き起こす可能性があるため、使用する必要がないため、より効率的である可能性があります。

foreach(DataRow row in filteredRows)
{
    tblFiltered.ImportRow(row);
}
于 2013-06-03T10:23:13.030 に答える