小试反射

之前在博客园看了《一句代码实现批量数据绑定》这篇文章的代码,才知道知道反射可以用来获取类的属性等信息。然后想到之前用三层架构+存储过程来做网站的时候,数据访问层的很多代码都是重复的,都是根据实体类的结构,填充好参数,然后调用相应的存储过程。于是就写了这个数据访问层的基类:

public class DAL<T> where T : class, new()
    {
        private static string TypeName;
        protected SQLHelper sqlExecuter;
        protected DAL()
        {
            TypeName = typeof(T).Name;
            sqlExecuter = new SQLHelper("");
        }

        #region 反射部分
        private PropertyInfo[] GetProperties()
        {
            return typeof(T).GetProperties();
        }
        //根据实体填充SqlParameter
        private List<SqlParameter> GetParameters(T entity, int tag)
        {
            List<SqlParameter> result = new List<SqlParameter>();
            SqlDbType tmpType;
            int tmpLength = 0;
            int EnableTag = 0;
            foreach (PropertyInfo eachProperty in GetProperties())
            {
                EnableTag = (eachProperty.GetCustomAttributes(typeof(ModelAttribute), true)[0] as ModelAttribute).EnableTag;
                if (!Common.Tools.TestBit(EnableTag, tag))
                    continue;
                tmpType = (eachProperty.GetCustomAttributes(typeof(ModelAttribute), true)[0] as ModelAttribute).DBDataType;
                tmpLength = (eachProperty.GetCustomAttributes(typeof(ModelAttribute), true)[0] as ModelAttribute).Length;
                result.Add(SQLHelper.MakeInParam2("@" + eachProperty.Name, tmpType, tmpLength, eachProperty.GetValue(entity, null)));
            }
            return result;
        }
        //填充实体
        private void SetValue(T entity, SqlDataReader rdr)
        {
            int index = 0;
            SqlDbType tmpType;
            foreach (PropertyInfo eachProperty in GetProperties())
            {
                index = (eachProperty.GetCustomAttributes(typeof(ModelAttribute), true)[0] as ModelAttribute).Index;
                tmpType = (eachProperty.GetCustomAttributes(typeof(ModelAttribute), true)[0] as ModelAttribute).DBDataType;

                switch (tmpType)
                {
                    case SqlDbType.NVarChar:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index, ""), null);
                        break;
                    case SqlDbType.VarChar:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index, ""), null);
                        break;
                    case SqlDbType.NText:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index, ""), null);
                        break;
                    case SqlDbType.Int:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index, 0), null);
                        break;
                    case SqlDbType.DateTime:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index,Common.Tools.GetNullDatetime()), null);
                        break;
                    default:
                        eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index), null);
                        break;
                }
                //eachProperty.SetValue(entity, SQLHelper.GetSqlResult(rdr, index, new object()), null);
            }
        }
        #endregion

        public virtual bool Add(T entity)
        {
            SqlParameter[] param = GetParameters(entity, 0).ToArray();
            return sqlExecuter.ExecuteNonQuery(CommandType.StoredProcedure, "Add" + TypeName, param) > 0;
            //return true;
        }

        public virtual bool Update(T entity)
        {
            SqlParameter[] param = GetParameters(entity, 1).ToArray();
            return sqlExecuter.ExecuteNonQuery(CommandType.StoredProcedure, "Update" + TypeName, param) > 0;
            //return true;
        }

        public virtual bool Del(int id)
        {
            SqlParameter param = SQLHelper.MakeInParam2("@id", SqlDbType.Int, 0, id);
            return sqlExecuter.ExecuteNonQuery(CommandType.StoredProcedure, "Del" + TypeName, param) > 0;
        }

        public virtual T GetOne(int id)
        {
            SqlParameter param = SQLHelper.MakeInParam2("@id", SqlDbType.Int, 0, id);
            using (SqlDataReader rdr = sqlExecuter.ExecuteReader(CommandType.StoredProcedure, "GetOne" + TypeName, param))
            {
                if (rdr != null && rdr.HasRows)
                {
                    rdr.Read();
                    T result = new T();
                    SetValue(result, rdr);
                    return result;
                }
                else
                    return null;
            }
        }

    }
public class ModelAttribute : Attribute
    {
        public SqlDbType DBDataType { get; set; }
        public int Length { get; set; }

        //按位标识增、删、改、查时属性是否需要填充
        public int EnableTag { get; set; }
        //读取时列的序号
        public int Index { get; set; }

        public ModelAttribute()
        {
            EnableTag = 0;
            Length = 0;
            Index = 0;
        }
    }
    public class Student
    {
        [Model(DBDataType = SqlDbType.Int, EnableTag = 2, Index = 0)]
        public int Id { get; set; }

        [Model(DBDataType = SqlDbType.NVarChar, Length = 20, EnableTag = 3, Index = 1)]
        public string Name { get; set; }

        [Model(DBDataType = SqlDbType.Int, EnableTag = 3, Index = 2)]
        public int Age { get; set; }
    }

这样的话,从DAL<T>继承过来的类,就已经具有增删改查的数据访问层的逻辑了

public class DALStudent : DAL<Student>
    {
        public DALStudent()
        {

        }
    }
protected void Page_Load(object sender, EventArgs e)
        {
            DALStudent st = new DALStudent();
            st.Add(new Student { Name = "zhicong", Age = 13, Id = 3 });
        }

当然,这只是小试,不知道具不具有实用性。。。。

posted @ 2011-04-23 21:21  ailove  阅读(498)  评论(1编辑  收藏  举报
返回顶端^