Asp.net中打造通用数据访问类(c#)[转]

 刚刚写的,可能里面会有漏洞,望指正.
     ASP。NET开发中, 业务实体需要通过数据访问层与数据库交互,因此,你必须为每个业务实体类编写相对应的数据访问层代码。以下代码解决了这个问题: 所有的业务实体只要派生自一个指定的类(这里是SwContent类),那么只须定义他与数据库相对应的字段属性,它所继承的Select(),Insert(),UpDate(),Delete()方法(无须重写)便可以完成(1),从数据库中获取指定数据填充实体类;(2),从指定实体对象获取数据插入到数据库中;(3),从指定实体对象获取数据更新数据库中对应的数据项;(4),删除数据。下面的主要代码是通过属性实现的。其思路是:实体类提供一个共公方法(在他们的基类中实现)可以返回IDataParameter的数组类型。parameterName标记属性名,Value是属性值。数据访问层代码对该数组进行矢代,构造Sql语句后执行操作。

 注意: 业务实体类的公共属性名必须与数据库的相关字段名保持一至,且数据库中的主键要保持一直(这里是Id)。

 为了兼容多层开发模式,我定义了一个 ISwDataProperty接口。SwContent类及他的派生类将实现该接口。

    public interface ISwDataProperty
    {
        int Id
        {
            get; //与数据库的主键对应,且所有表的主键都要相同。
        }

        string Table
        {
            get; //与实体类相对应的数据库表名
        }

        object this[int index]  //存取访问器,主要使用属性实现,代码在后面贴出
        {
            get; 
            set;
        }
 
 void AcceptChanges();    //只用于UpDate时;与DataSet的AcceptChanges()方法作用类似,若不调用,则表示更新数据库中的所有项;调用他,则只更新在调用后所设置的数据项。

        IDataParameter[] GetSwDataParameters();  //返回与实体类相关的参数列表。
    }

 /////////////////////////////////////////////////////////////////////////////
 因此我还定义了SwDataParameter类(我们只需要使用ParameterName,Value两个属性。):
    public class SwDataParameter:IDataParameter
    {
        private object _value;
        private string _parameterName;

        #region IDataParameter 成员

        public DbType DbType
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public ParameterDirection Direction
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public bool IsNullable
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public string ParameterName
        {
            get
            {
                return _parameterName;
            }
            set
            {
                _parameterName = value;
            }
        }

        public string SourceColumn
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public DataRowVersion SourceVersion
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public object Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
            }
        }

        #endregion
    }

 /////////////////////////////////////////////////////////////////////////////
 
 在贴出业务实体基类的ISwDataProperty实现方式之前,我们定义一个属性类,他只用来做标记(做此标记的属性将不会用来进行与数据库相关连的操作)。

    [AttributeUsage(AttributeTargets.Property)]
    public class SwNotDataParameterAttribute : Attribute
    {
        /// <summary>
        /// 只用做标记,指示该属性不是数据库字段
        /// </summary>
        public SwNotDataParameterAttribute()
        {
        }
    }

 /////////////////////////////////////////////////////////////////
 在ISwDataProperty中定义的3个属性都要加上[SwNotDataParameter()]标记:

    public abstract class SwContent:ISwDataProperty
    {
        protected int _id;
        protected string _table;
        protected object _upDateRef = null;

        public SwContent()
        {
        }

        #region ISwDataProperty 成员

        [SwNotDataParameter()]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }

        [SwNotDataParameter()]
        public string Table
        {
            get
            {
                return _table;
            }
        }

        [SwNotDataParameter()]
        public object this[int index]
        {
            get
            {
                int i = 0;
                object obj=null;
                foreach (PropertyInfo item in this.GetType().GetProperties())
                {
                    if (item.GetCustomAttributes(typeof(SwNotDataParameterAttribute), true).Length < 1)
                    {
                        if (i == index)
                        {
                            if (item.GetGetMethod().ReturnType == typeof(BoolEnum)) //BoolEnum是我自定义的枚举。
                            {
                                return Convert.ToInt32(item.GetValue(this, null));
                            }
                            obj = item.GetValue(this, null);
                            if (item.GetGetMethod().ReturnType == typeof(string) &&
                                string.IsNullOrEmpty((string)obj))
                            {
                                return string.Empty;
                            }
                            break;
                        }
                        i++;
                    }
                }
                return obj;
            }
            set
            {
                int i = 0;
                foreach (PropertyInfo item in this.GetType().GetProperties())
                {
                    if (item.GetCustomAttributes(typeof(SwNotDataParameterAttribute), true).Length < 1)
                    {
                        if (i == index)
                        {
                            if (item.GetGetMethod().ReturnType == typeof(BoolEnum))
                            {
                                item.SetValue(this, (BoolEnum)value, null);
                                break;
                            }
                            item.SetValue(this, value, null);
                            break;
                        }
                        i++;
                    }
                }
            }
        }

        public void AcceptChanges()
        {
            _upDateRef = this.MemberwiseClone();
        }

        public IDataParameter[] GetSwDataParameters()
        {
            PropertyInfo[] swProInfo = this.GetType().GetProperties();
            int i = 0;
            int j = 0;
            IDataParameter[] _swDataParameters = new SwDataParameter[swProInfo.Length];
            foreach (PropertyInfo item in swProInfo)
            {
                if (item.GetCustomAttributes(typeof(SwNotDataParameterAttribute),true).Length < 1)
                {
                    if (_upDateRef == null || ((ISwDataProperty)_upDateRef)[j].ToString() != this[j].ToString())
                    {
                        _swDataParameters[i] = new SwDataParameter();
                        _swDataParameters[i].ParameterName = item.Name;
                        _swDataParameters[i].Value = this[j];
                        i++;
                    }
                    j++;
                }
            }
            Array.Resize<IDataParameter>(ref _swDataParameters, i);
            return _swDataParameters;
        }

        #endregion

        public void Select()
        {
            _upDateRef = null;
            SwContentOperate.Select(this);
        }

        public virtual bool Insert()
        {
            _upDateRef = null;
            return SwContentOperate.Insert(this);
           
        }

        public bool UpDate()
        {
            return SwContentOperate.UpDate(this);
        }

        public bool Delete()
        {
            return SwContentOperate.Delete(this.Id, this.Table);
        }
    }
}


 ///////////////////////////////////////////////////////////////////////////////////////////////////
 这里是数据访问类:
    public class SwContentOperate
    {
        public static void Select(ISwDataProperty obj)
        {
            try
            {
                SqlConnection newConnect = SwConnect.Create();

                string sql = "select * from "+obj.Table+" where Id="+obj.Id;
                SqlDataAdapter swDataAdapter = new SqlDataAdapter(sql, newConnect);
                newConnect.Open();
                DataSet swDS = new DataSet();
                swDataAdapter.Fill(swDS, obj.Table);
                newConnect.Close();

                DataRow swDataRow = swDS.Tables[0].Rows[0];
                if (swDS.Tables[0].Rows.Count <1)
                {
                    obj = null;
                    swDS.Clear();
                    return;
                }

                IDataParameter[] swPC = obj.GetSwDataParameters();
                int i = 0;
                object objVal = null;
                foreach (IDataParameter item in swPC)
                {
                    try
                    {
                        objVal = swDataRow[item.ParameterName];
                    }
                    catch
                    {
                        objVal = null;
                    }
                    obj[i] = objVal;
                    i++;
                }
                swDS.Clear();
            }
            catch(Exception e)
            {
                throw new SwLogException("ERROR", e);
            }
        }


        public static bool Insert(ISwDataProperty obj)
        {
            try
            {
                SqlConnection newConnect = SwConnect.Create();

                string sql = "insert into "+obj.Table+" (";
                string sqlLast = ")values(";
                SqlCommand swCommand = new SqlCommand();
                SqlParameter swParameter;
                IDataParameter[] swPC = obj.GetSwDataParameters();
                int i = 0;
                foreach (IDataParameter item in swPC)
                {
                    if (i != swPC.Length - 1)
                    {
                        sql += item.ParameterName + ",";
                        sqlLast += "@" + item.ParameterName + ",";
                    }
                    else
                    {
                        sql += item.ParameterName;
                        sqlLast += "@" + item.ParameterName + ")";
                    }
                    swParameter = new SqlParameter();
                    swParameter.ParameterName = "@"+item.ParameterName;
                    swParameter.Value = item.Value;
                    swCommand.Parameters.Add(swParameter);
                    i++;
                }
                swCommand.CommandText = sql + sqlLast;
                swCommand.Connection = newConnect;
                newConnect.Open();
                swCommand.ExecuteNonQuery();
                newConnect.Close();
            }
            catch(Exception e)
            {
                throw new SwLogException("ERROR", e);
            }
            return true;
        }

        public static bool UpDate(ISwDataProperty obj)
        {
            try
            {
                SqlConnection newConnect = SwConnect.Create();

                string sql = "update "+obj.Table+" set ";
                SqlCommand swCommand = new SqlCommand();
                SqlParameter swParameter;
                IDataParameter[] swPC = obj.GetSwDataParameters();
                if (swPC.Length < 1)
                {
                    newConnect.Close();
                    return true;
                }
                int i = 0;
                swCommand.Parameters.Add(new SqlParameter("@Table",obj.Table));
                foreach (IDataParameter item in swPC)
                {
                    if (i != swPC.Length - 1)
                    {
                        sql += item.ParameterName + "=@" + item.ParameterName + ",";
                    }
                    else
                    {
                        sql += item.ParameterName + "=@" + item.ParameterName+" where Id="+obj.Id;
                    }
                    swParameter = new SqlParameter();
                    swParameter.ParameterName = "@"+item.ParameterName;
                    swParameter.Value = item.Value;
                    swCommand.Parameters.Add(swParameter);
                    i++;
                }
                swCommand.CommandText = sql;
                swCommand.Connection = newConnect;
                newConnect.Open();
                swCommand.ExecuteNonQuery();
                newConnect.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static bool Delete(int id,string table)
        {
            try
            {
                SqlConnection newConnect = SwConnect.Create();

                string sql = "delete from "+table+" where id=" + id;
                SqlCommand swCommand = new SqlCommand(sql, newConnect);
                newConnect.Open();
                swCommand.ExecuteNonQuery();
                newConnect.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }
    }
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 实体类只要继承SwContent类既可。
    public class NewClass:SwContent,ISwDataProperty
    {
        private int _parentId;
        private string _name;
        private string _text;

        public SwContentOperate()
        {
            _table = "DatabaseTable"; //在构造函数中硬编码对应的表名。
        }

        public int ParentId
        {
            get
            {
                return _parentId;
            }
            set
            {
                _parentId = value;
            }
        }
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        public string Text
        {
            get
            {
                return _text;
            }
            set
            {
                _text = value;
            }
        }
 ....................

 //////////////////////
 
 页面测试:
 NewClass obj=new NewClass();
 obj.Id=1;
 obj.Select(); //获取数据库数据。
 obj.Text="Test"; 
 obj.UpDate(); //更新数据。
 obj.Text="Test1";
 obj.AcceptChanges(); //前面的设置obj.Text="Test1"将不会被更新到数据库。
 obj.UpDate();

 这是从几个装配件中整理出来的,所以代码比较混乱,如有错误,请海涵。

posted @ 2008-04-13 19:49  彭成刚  阅读(786)  评论(0编辑  收藏  举报