4

C#でDataTableに値の範囲の制約を作成することは可能ですか?

DataTableに列を動的に追加しています:

this.PrimaryCorrelationMatrix.Columns.Add(sName, typeof(int));

ただし、この列内のすべての値を[0、10]の整数にします。このような制約をDataTableに直接実装できますか?

私が考えることができる次善のオプションは、typeof(int)の代わりにtypeof(specialObj)を使用して、可能な値[0、10]でオブジェクトを作成することです。

4

3 に答える 3

7

e.ProposedValueこれを行う1つの方法は、DataTableのColumnChangingイベントでを検査することです。

特定の列に制約を設定するには、DataColumnのExtendedPropertiesコレクションを使用して、これらの制約をチェックするためのフラグとして機能します。

DataTable dt = new DataTable();
DataColumn dc = new DataColumn("Range", typeof(int));
dc.ExtendedProperties.Add("Min", 0);
dc.ExtendedProperties.Add("Max", 10);
dt.Columns.Add(dc);
dt.ColumnChanging += dt_ColumnChanging;

ColumnChangingイベントでは、これらのプロパティが存在するかどうかを確認してから、次のように使用します。

void dt_ColumnChanging(object sender, DataColumnChangeEventArgs e) {
  if (e.Column.ExtendedProperties.ContainsKey("Min") &&
      e.Column.ExtendedProperties.ContainsKey("Max")) {
    int min = (int)e.Column.ExtendedProperties["Min"];
    int max = (int)e.Column.ExtendedProperties["Max"];
    if ((int)e.ProposedValue < min) e.ProposedValue = min;
    if ((int)e.ProposedValue > max) e.ProposedValue = max;
  }
}
于 2013-11-20T14:51:52.037 に答える
2

データテーブルを忘れてクラスを使用することをお勧めします。データ注釈を使用して、モデルを検証できます。

この属性を使用して、特定のプロパティの値の範囲を検証します/

このコードは、指定された記事(範囲の検証を行うクラスの例)から抽出されます。

public class Product
{

  [Range(5, 50)]
  public int ReorderLevel { get; set; }

  [Range(typeof(Decimal),"5", "5000")]
  public decimal ListPrice { get; set; }

}

クラスを使用することの多くの利点を見つけるでしょう。

于 2013-11-21T02:21:01.070 に答える
0

これは古い投稿ですが、言及する価値のあるアクセスデータベースのOleDbDataAdapter.FillSchemaによって満たされていないCheck_Constraintsを同期するソリューションを使用しています。OleDbConnectionを使用してGetOleDbSchemaTableを取得し、行をforeach()して検証テキスト式を抽出し、適切なTable.ColumnChangingイベントに接続された適切なTable&Columnに匿名のデリゲートを作成しました。次に、Accessスキーマによって提供される文字列検証は、ここで説明する便利なEval()関数によって動的に評価されます。私のコードがあります:

DataTable schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Check_Constraints, null);
// Attach delegate Eval() of each Check_Constraints on proper Table/Column
foreach (DataRow myField in schemaTable.Rows)
{
    string constraint_name = "";
    string check_clause = "";
    foreach (DataColumn myProperty in schemaTable.Columns)
    {
        if (myProperty.ColumnName == "CONSTRAINT_NAME")
            constraint_name = myField[myProperty.ColumnName].ToString();
        if (myProperty.ColumnName == "CHECK_CLAUSE")
            check_clause = myField[myProperty.ColumnName].ToString();
    }
    var rule = constraint_name.Replace("[", "").Replace("]", "").Split('.');
    if (rule.Length == 3 && dataset.Tables.Contains(rule[0]) && dataset.Tables[rule[0]].Columns.Contains(rule[1]) && String.IsNullOrEmpty(check_clause) == false)
    {
        dataset.Tables[rule[0]].ColumnChanging += delegate (object sender, DataColumnChangeEventArgs e)
        {
            if (e.Column.ColumnName == rule[1] && Convert.ToBoolean(ToolBox.Eval(e.ProposedValue + check_clause)) == false)
            {
                throw new Exception("Tabela: " + rule[0] + ", coluna: " + rule[0] + ", cheque: " + check_clause);
            }
        };
        Debug.WriteLine(rule[0] + "." + rule[1] + ": " + check_clause);
    }
}
于 2017-09-19T21:25:07.410 に答える