泛型+反射=动态实现增删改查

反射知识回顾

//1通过Assembly动态加载一个程序集
Assembly assembly = Assembly.Load("KangHui.Common");
//2通过Type获取T类型
Type type = typeof(T);
//3过类型可以创建一个对象
T obj=(T)Activator.CreateInstance(type);
//4通过类型获取所有公共属性集合
PropertyInfo[] prolists = type.GetProperties();
//5通过类型获取方法的集合
 MethodInfo[] methods = type.GetMethods();


Type type = typeof(T);
PropertyInfo[] pro = type.GetProperties();
string id = pro[0].Name;
//如果T是类名,则pro[0].Name的意思是:获取该类第一个属性名称,即Id.

反射的缺点

  1. 生成meta源文件,让你的DLL文件的体积变大;

  2. 反射会影响程序的性能;

  3. 不安全 比如:一个泛型方法需要一个class 但是传入的是一个int ,而我们并没有进行泛型约束,那么此时这个程序就报错了。

以Add()为实例——反射的实现

原始静态代码:

/// <summary>
/// 增加一条数据
/// </summary>
public int Add(ThreeDemo.Model.UsersModel model)
{
    
    
    StringBuilder strSql = new StringBuilder();
    strSql.Append("insert into Users(");
    strSql.Append("UserName,Pwd,DistrictID,QQ,Phone,Sex,LoginNumber,LastLoginTime,Manage)");
    strSql.Append(" values (");
    strSql.Append("@UserName,@Pwd,@DistrictID,@QQ,@Phone,@Sex,@LoginNumber,@LastLoginTime,@Manage)");
    strSql.Append(";select @@IDENTITY");
    SqlParameter[] parameters = {
    
    
			new SqlParameter("@UserName", SqlDbType.NVarChar,50),
			new SqlParameter("@Pwd", SqlDbType.NVarChar,50),
			new SqlParameter("@DistrictID", SqlDbType.Int,4),
			new SqlParameter("@QQ", SqlDbType.NVarChar,50),
			new SqlParameter("@Phone", SqlDbType.NVarChar,50),
			new SqlParameter("@Sex", SqlDbType.Int,4),
			new SqlParameter("@LoginNumber", SqlDbType.Int,4),
			new SqlParameter("@LastLoginTime", SqlDbType.DateTime),
			new SqlParameter("@Manage", SqlDbType.Int,4)};
    parameters[0].Value = model.UserName;
    parameters[1].Value = model.Pwd;
    parameters[2].Value = model.DistrictID;
    parameters[3].Value = model.QQ;
    parameters[4].Value = model.Phone;
    parameters[5].Value = model.Sex;
    parameters[6].Value = model.LoginNumber;
    parameters[7].Value = model.LastLoginTime;
    parameters[8].Value = model.Manage;

    object obj = DbHelperSQL.GetSingle(strSql.ToString(),"", parameters);
    if (obj == null)
    {
    
    
        return 0;
    }
    else
    {
    
    
        return Convert.ToInt32(obj);
    }
}

改为动态加载:

/// <summary>
/// 增加一条数据
/// </summary>
public int Add<T>(T t)
{
    
    
    Type type = typeof(T);
    PropertyInfo[] propertyInfo = type.GetProperties();
    StringBuilder str1 = new StringBuilder();
    StringBuilder str2 = new StringBuilder();
    for (int i=1;i<propertyInfo.Length;i++)
    {
    
    
        str1.Append(propertyInfo[i].Name + ",");
        str2.Append("@" + propertyInfo[i].Name + ",");
    }
    str1.Remove(str1.Length - 1, 1);
    str2.Remove(str2.Length - 1, 1);

    StringBuilder strSql = new StringBuilder();
    strSql.Append("insert into "+type.Name.Replace("Model","")+"(");
    strSql.Append(str1+")");
    strSql.Append(" values (");
    strSql.Append(str2+")");

    List<SqlParameter> par = new List<SqlParameter>();
    for(int i = 1; i < propertyInfo.Length; i++)
    {
    
    
    	par.Add(new SqlParameter("@" + propertyInfo[i].Name + "", propertyInfo[i].GetValue(t)));
    }
    SqlParameter[] sqlParameters = par.ToArray();

    int rows = DbHelperSQL.ExecuteSql(strSql.ToString(), connString, sqlParameters);
    if (rows > 0)
    {
    
    
    	return rows;
    }
    else
    {
    
    
    	return 0;
    }
}

GetModel()

/// <summary>
/// 得到一个对象实体
/// </summary>
public T GetModel<T>(int UserId)
{
    
    
    StringBuilder str1 = new StringBuilder();
    Type type = typeof(T);
    PropertyInfo[] propertyInfos = type.GetProperties();
    string id = propertyInfos[0].Name;
    foreach (PropertyInfo item in propertyInfos)
    {
    
    
    	str1.Append(item.Name + ",");
    }
    str1.Remove(str1.Length - 1, 1);

    StringBuilder strSql = new StringBuilder();
    if (str1 != null)
    {
    
    
    	strSql.Append("select top 1 "+str1+" from "+type.Name.Replace("Model",""));
    }
    strSql.Append(" where "+id+"=@"+id+"");

    SqlParameter[] parameters = {
    
     new SqlParameter("@"+id+"", SqlDbType.Int,4) };
    parameters[0].Value = UserId;

    DataSet ds = DbHelperSQL.Query(strSql.ToString(), connString, parameters);
    if (ds.Tables[0].Rows.Count > 0)
    {
    
    
        return DataRowToModel<T>(ds.Tables[0].Rows[0]);
    }
    else
    {
    
    
        return null;
    }
}

DataRowToModel()改写

//原始形态
private LoginModel DataRowToModel(DataRow dr)
{
    
    
    LoginModel model = new LoginModel();
    if (!dr.IsNull("Id")){
    
    
        model.Id = Convert.ToInt32(dr["Id"]);
    }
    if (!dr.IsNull("LoginName")){
    
    
        model.LoginName = dr["LoginName"].ToString();
    }
    if (!dr.IsNull("Pwd")){
    
    
        model.status = dr["Pwd"].ToString();
    }
    if (!dr.IsNull("status")){
    
    
        model.status = dr["status"].ToString();
    }
    return model;
}
//改写为动态转换形式
private T DataRowToModel<T>(DataRow dr)
{
    
    
    Type type = typeof(T);
    T model = (T)Activator.CreateInstance(type);
    PropertyInfo[] pro = type.GetProperties();
    if(dr!=null){
    
       
    	for(int i=0;i<pro.Length;i++){
    
    
            pro[i].SetValue(model, dr[i]);
            //循环赋值,model为对象,dr[i]为要赋的值
        }
    }
    return model;
}

typeof() 和 GetType()区别

  1. typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。
  2. GetType()方法继承自Object,所以C#中任何对象都具有GetType()方法,它的作用和typeof()相同,返回Type类型的当前对象的类型。

比如有这样一个变量 i:
Int32 i = new Int32();
i.GetType()返回值是Int32的类型,但是无法使用typeof(i),因为i是一个变量,如果要使用typeof(),则只能:typeof(Int32),返回的同样是Int32的类型。

猜你喜欢

转载自blog.csdn.net/qq_41802224/article/details/109091987
今日推荐