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