65.9K
CodeProject 正在变化。 阅读更多。
Home

为 ADO.NET 中的数据列添加自定义验证

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (5投票s)

2005 年 11 月 14 日

2分钟阅读

viewsIcon

56703

downloadIcon

518

本文档描述了如何在 ADO.NET 中为数据列添加自定义验证。

引言

目前,DataTable 在创建扩展数据列时,对数据列中的自定义验证的支持非常有限。本文档展示了如何通过扩展 ADO.NET DataColumn 来为数据列添加正则表达式验证功能。DataColumn 可以在其发生变化时,通过验证器进行验证。

动机

ADO.NET DataColumn 通过实现唯一约束来支持唯一值,但是我们如何添加自定义验证,这些验证可能由业务规则控制(例如正整数或某些正则表达式验证)? 一种选择是使用从抽象 Constraint 类派生的自定义约束,但这是一项繁琐的任务。

因此,我们需要对 DataColumn 进行一些扩展。扩展数据列 正是这样做的,它允许用户使用验证器类提供自己的验证逻辑,该验证器类返回验证是否成功。

该解决方案的核心是 DataColumnEx 类,它在构造函数中接收 DataTable、名称和验证器作为参数。

IValidator 接口

所有参与 datacolumnEx 数据验证的验证器都需要实现 IValidator 接口,该接口具有一个名为 IsValid 的方法。

namespace DataColumnEx
{
    /// <summary>
    /// Base interface which will be implemented
    /// by classes to validate the values
    /// in the extended datacolumn
    /// </summary>

    public interface IValidator
    {
       bool IsValid(object value);
    }
}

验证器通过执行指定规则接收一个对象,并返回一个布尔值,指示验证是否成功。 显而易见的是,验证的范围可以从简单地限制值到正整数,到封装业务规则的更复杂的内容。

将任何业务逻辑封装到单独的类中,可以将控制验证的业务逻辑与扩展数据列分离。

DataColumnEx 类

DataColumnEx 在其 Validator 属性中接收一个类型为 IValidator 的类。 DataColumnEx 订阅其所属表(如在构造函数中指定)的 ColumnChanged 事件,并在那里调用验证器。 DataColumnEx 类还具有一个属性 RejectChangesOnError,指示对行所做的更改是否应该被拒绝。

using System;
using System.Data;

namespace DataColumnEx
{

    /// <summary>
    /// Extended data column which Inherits from data column and adds the
    /// capability to validate data as per rules specified in the validator
    /// </summary>

    public class DataColumnEx : DataColumn
    {

        private IValidator m_validator;
        private DataTable m_table;
        private bool m_rejectChangesOnError;
        private ResourceMgr m_resMgr = 
                new ResourceMgr("DataColumnEx.ErrorStrings");
    
        /// <summary>
        /// Overloaded Constructor
        /// </summary>
        /// <param name="table">Table to which this column belongs</param>
        /// <param name="name">Name of the column</param>
        /// <param name="validator">Validator 
        ////       to validate the proposed value in the column</param>
    
        public DataColumnEx(DataTable table, string name, IValidator validator)
        {
            ColumnName = name;
            m_validator = validator;
            m_table = table;
            DataType = typeof(string);

            if (m_table != null)
            {
                m_table.ColumnChanged += 
                   new DataColumnChangeEventHandler(OnColumnChanged);
            }
        }

        /// <summary>
        /// Overloaded Constructor
        /// </summary>
        /// <param name="table">Table to which this column belongs</param>
        /// <param name="name">Name of the column</param>
        /// <param name="validator">Validator to validate
        ///        the proposed value in the column</param>
        /// <param name="columnType">Data type of this column</param>
        
        public DataColumnEx(DataTable table, string name, 
                   IValidator validator, Type columnType)

        {
            ColumnName = name;
            m_validator = validator;
            m_table = table;
            DataType = columnType;

            if (m_table != null)
            {
                //Subscribe to the column changed event
                m_table.ColumnChanged += 
                  new DataColumnChangeEventHandler(OnColumnChanged);
            }
        }

        /// <summary>
        /// Sets or gets the validator which will validate the proposed value
        /// </summary>

        public IValidator Validator
        {
            get { return m_validator; }
            set { m_validator = value; }
        }
        
        /// <summary>
        /// Sets or gets whether the changes made to the row
        ///     should be rejected if the validation
        ///     fails for the column
        /// </summary>
        public bool RejectChangesOnError
        {
            get { return m_rejectChangesOnError; }
            set { m_rejectChangesOnError = value; }
        }

        private void OnColumnChanged(object sender, DataColumnChangeEventArgs e)
        {
            if (e.Column == this)
            {
                object obj = e.ProposedValue;
        
                //If not valid,then reject changes if the flag is set
                if (!m_validator.IsValid(obj))
                {
                    if (m_rejectChangesOnError)
                        e.Row.RejectChanges();
                    throw new Exception(m_resMgr.GetString("S_ERR_INVALID_DATA"));
                }
            }
        }
    }
}

结论

我提供了一些非常基本的场景,可以在其中验证数据列以限制输入。 这个想法可以扩展到更复杂的场景,以适应手头的业务需求。

为 ADO.NET 中的数据列添加自定义验证 - CodeProject - 代码之家
© . All rights reserved.