DataColumns の Expression プロパティを使用して、DataTable を使用してデータ行の計算を実行しようとしています。msdn
行に式を適用しているときに例外が発生した場合、デフォルト値が使用されることがわかりました。それはまさに、問題のある行に私が望むものです。問題は、後続の各行が式を評価する代わりにデフォルト値を使用することです。
この例では、2 つの列と 10 行で構成されるベース テーブルから始めます。最初の列は、-5 から 5 の範囲で自動インクリメントされる列です。2 番目の列は常に 3 です。
「3」列を最初の列で割る式で 3 番目の列を追加します。これにより、1 つの行に対して div0 例外が発生します。
その 1 行については、指定したデフォルト値を使用したいと考えています。ただし、残りの 4 行にもデフォルト値が適用されます。
出力:
-5 3 -0.6
-4 3 -0.75
-3 3 -1
-2 3 -1.5
-1 3 -3
0 3 -33 //Expected
1 3 -33 //I want it to continue evaluating the expression, not default
2 3 -33
3 3 -33
4 3 -33
個々の行に問題がある場合にデフォルト値を使用し、後続の行に引き続き式を使用するように処理を追加するにはどうすればよいですか?
ここで説明されているように IIF を単純に使用してこのような問題をチェックすることはできないことに注意してください。使用される式は動的であり、データをカスタマイズする方法としてユーザーから提供されるためです。
これを再現する完全なコード:
using System;
using System.Data;
namespace DataSetExpressionTest
{
public class SO
{
private static DataTable table = null;
private static void Main(string[] args)
{
table = CreateBaseTable();
//If there is a problem only in some rows of the table, the rows before the error are calculated using the expression. All rows afrer use the default value
DataColumn onlyOneException = new DataColumn()
{
ColumnName = "One-Ex",
Expression = "third / index",
DefaultValue = -33
};
AddCalculationToTable(onlyOneException);
PrintDataTable(table);
Console.ReadLine();
}
private static void AddCalculationToTable(DataColumn calculationColumn)
{
//You can wrap individual stats in try/catch blocks. If there is an exception in a calc, it will use the default value specified
try
{
table.Columns.Add(calculationColumn);
}
catch (Exception e)
{
Console.WriteLine("Caught a calculation exception while adding column {0}. Will use default value instead!!", calculationColumn.ColumnName);
}
}
private static DataTable CreateBaseTable()
{
DataTable table = new DataTable();
// Create 3s column.
DataColumn threeColumn = new DataColumn
{
DataType = Type.GetType("System.Decimal"),
ColumnName = "third",
DefaultValue = 3
};
//Create icrementing index column
DataColumn indexColumn = new DataColumn
{
DataType = Type.GetType("System.Decimal"),
ColumnName = "index",
AutoIncrement = true,
AutoIncrementSeed = -5
};
// Add columns to DataTable.
table.Columns.Add(indexColumn);
table.Columns.Add(threeColumn);
for (var i = 0; i < 10; i++)
{
table.Rows.Add(table.NewRow());
}
return table;
}
public static void PrintDataTable(DataTable table)
{
foreach (DataColumn column in table.Columns)
{
Console.Write(column.ColumnName + " ");
}
Console.WriteLine();
foreach (DataRow dataRow in table.Rows)
{
foreach (var item in dataRow.ItemArray)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
}
}
}