ColumnChanging事件中的DataSet验证

时间:2011-11-22 20:34:20

标签: c# ado.net

在包含DataSet事件的部分类中,我有以下内容:

protected override void OnColumnChanging(System.Data.DataColumnChangeEventArgs e)
{
    switch (e.Column.ColumnName)
    {
        case "ColumnA":
        {
            int value = GetValue(e.ProposedValue.ToString());

            if (value == -1)
            {
                e.Row.SetColumnError("ColumnA", string.Format("ColumnA could not map [{0}] to a valid value", e.ProposedValue));
                //e.ProposedValue = "";
           }

           break;
       }

       base.OnColumnChanging(e);
}

当我检查错误并获取行的列错误时,我会在GetValue(...)返回-1时看到相应的消息。我还看到其中包含错误数据的列仍包含该错误值。我的印象是调用SetColumnError(...)将拒绝对该列(ColumnA)所做的更改:How to: Validate Data During Column Changes

  

通过设置列错误(SetColumnError)拒绝建议的值   来自列更改事件处理程序。

所以,当我尝试做类似以下的事情时:

TypedDataSet set = new TypedDataSet();
TypedDataTable.TypedDataRow row = set.TypedDataTable.NewRow();
row.ColumnA = "Bad Data";
set.TypedDataTable.AddTypedDataRow(row);

我会看到验证码执行,但ColumnA的值保留:“Bad Data”。如果我设置e.ProposedValue = null,我可以看到值的变化。

更新

为RowsChanging或ColumnsChanging添加事件处理程序也会产生类似的结果。

public override void BeginInit()
{
    base.BeginInit();
    TypedRowChanging += new TypedRowChangeEventHandler(TypedDataTable_TypedRowChanging);
    ColumnChanging += new DataColumnChangeEventHandler(TypedDataTable_ColumnChanging);
}

两个事件处理程序中的代码都很简单,并且会调用e.Row.SetColumnError(“ColumnA”,“some some”)。所以我原来的问题仍然存在:

如果在列上设置了列错误,应该怎么办?如果它保留值,则变为空,42?

2 个答案:

答案 0 :(得分:0)

根据您链接的文档,您不希望覆盖OnColumnChanged - 您希望为ColumnChanged事件添加事件处理程序。尝试使用那里提供的示例代码作为起点。

答案 1 :(得分:0)

经过大量测试和工作后,我得出的结论是,当在特定列上设置列错误时,该列会保留该值。我目前的解决方案是检查整个DataSet上的错误,然后继续将这些错误聚合为错误处理格式

TypedDataSet set = new TypedDataSet();
TypedDataTable.TypedDataRow row = set.TypedDataTable.NewRow();
row.ColumnA = "Bad Data";
set.TypedDataTable.AddTypedDataRow(row);

// At this point the DataSet has column errors and can be checked for...
if (set.HasErrors)
{
    // Build some error string container here
    TypedDataSet.TypedDataRow row = tempSet.TypedDataTable.Single();

    var errors = from column in row.GetColumnsInError()
                 select row.GetColumnError(column);

    foreach (var error in errors)
    {
        // Add to error container here
    }
}

在此之后,我检查我的错误容器中是否有任何数据。我认为列保留值是有意义的,这样程序员就可以访问该值,并且可以在调用SetColumnError(...)时包含它。