c#反射与泛型

 

解释都在注释里了,会不断更新

 

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class DBHelper<T> where T : class, new()
    {
        //获取数据库连接名称(在appsettings.json配置文件下配置)
        private static string con = "Data Source=.;Initial Catalog=hahha;user=sa;password=010806wpz.;";
        #region 查询
        /// <summary>
        /// 查询   返回list泛型集合
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public List<T> Query(string where)
        {
            DataTable tb = new DataTable();
            List<T> list = new List<T>();
            string sql = GetQuerySql();
            sql += where;
            //将连接字符串赋值,获取到一个新实例
            using (SqlConnection connection = new SqlConnection(con))
            {
                //打开数据库的连接
                connection.Open();
                //实例化sqlcommand
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(command);
                    sqlDataAdapter.Fill(tb);
                    //获取T的类型
                    Type type = typeof(T);
                    //循环行
                    for (int i = 0; i < tb.Rows.Count; i++)
                    {
                        //实例化T,每一次都需要实例化new 对象
                        //Activator.CreateInstance:使用指定类型的无参数构造函数创建指定类型的实例。
                        //参数:Type:要创建的对象类型
                        //返回值:一个对新创建对象的引用(一个新创建的对象)包含数据表的所有字段
                        Object obj = Activator.CreateInstance(type);
                        for (int j = 0; j < tb.Columns.Count; j++)
                        {
                            //获取列的名称及类型 
                            //tb.Columns[j].ColumnName代表每一列字段的名称(例如:ID,Name)
                            //type.GetProperty:通过字段名称返回一个对象
                            //入参:要获取的属性名的字符串
                            //返回值(出参):返回符合指定要求的属性的对象(包括:字段类型,字段名称等)返回值类型为PropertyInfo
                            PropertyInfo info = type.GetProperty(tb.Columns[j].ColumnName);//赋值
                            #region 类型的判断并赋值
                            //int类型
                            if (tb.Columns[j].DataType == typeof(Int32))
                            {
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null)
                                {
                                    //obj.setValue(info,12);
                                    int num = int.Parse(tb.Rows[i][j].ToString());
                                    //info只是用作暂存
                                    //SetValue方法:使用可选索引值设置指定对象的属性值  
                                    //参数:  
                                    //第一个参数:要设置其属性值的对象。  
                                    //第二个参数:新的属性值。
                                    info.SetValue(obj, int.Parse(tb.Rows[i][j].ToString()), null);
                                    //上面那一行代码的意思是:将obj对象中的属性挨个遍历赋值成对应的值
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, 0, null);
                                }
                            }

                            //float类型
                            else if (tb.Columns[j].DataType == typeof(float))
                            {
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null)
                                {
                                    info.SetValue(obj, float.Parse(tb.Rows[i][j].ToString()), null);
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, 0.0f, null);
                                }
                            }

                            //datetime
                            else if (tb.Columns[j].DataType == typeof(DateTime))
                            {
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null)
                                {
                                    info.SetValue(obj, DateTime.Parse(tb.Rows[i][j].ToString()), null);
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, DateTime.Now, null);
                                }
                            }

                            //double
                            else if (tb.Columns[j].DataType == typeof(double))
                            {
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null)
                                {
                                    info.SetValue(obj, double.Parse(tb.Rows[i][j].ToString()), null);
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, 0.00, null);
                                }
                            }
                            //GUID
                            else if (tb.Columns[j].DataType == typeof(Guid))
                            {
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null && !tb.Rows[i][j].ToString().Equals(""))
                                {
                                    info.SetValue(obj, Guid.Parse(tb.Rows[i][j].ToString()), null);
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, Guid.Parse("00000000-0000-0000-0000-000000000000"), null);
                                }

                            }
                            else
                            {
                                //string
                                //有没有可能空值?
                                if (tb.Rows[i][j] != null)
                                {
                                    info.SetValue(obj, tb.Rows[i][j].ToString(), null);
                                }
                                else
                                {
                                    //null值的情况
                                    info.SetValue(obj, "", null);
                                }
                            }
                            #endregion
                        }
                        //将object 类型强转对应的类型
                        //集合中添加这一条数据
                        list.Add((T)obj);
                    }
                }
            }
            return list;
        }
        //拼接查询语句
        public string GetQuerySql()
        {
            Type type = typeof(T);
            string sql = "";
            //type.Name获取类的名称
            sql = "select * from " + type.Name + " where 1=1 ";
            return sql;
        }
        #endregion

        #region 修改
        public int Update(int Id, T model)
        {
            int flag = 0;
            //获取sql
            string sql = GetUpdateSql(Id,model);
            using (SqlConnection connection = new SqlConnection(con))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    flag = command.ExecuteNonQuery();
                }
            }
            return flag;
        }
        public string GetUpdateSql(int Id,T model)
        {
            string value = "";
            //首先定义修改的字段及数据,只需一个变量即可,因为修改语句字段及值是在一块的,所以不需要定义键值对
            //其次获取t所有的类型
            //获取之后获取所有字段
            //遍历保存了所有字段的数组
            //判断传进来的字段不是id
            //判断每个字段值是否为空
            //判断下标值+1是否等于当前的个数,等于的话就代表最后一个字段,不需要加,
            Type type = model.GetType();
            PropertyInfo[] info= type.GetProperties();
            for (int i = 0; i < info.Length; i++)
            {
                if (!info[i].Name.Contains("Id"))
                {
                    if (info[i].GetValue(model) != null)
                    {
                        if (i + 1 == info.Length)
                        {
                            //在数据库中即使是int类型的也可以用两个单引号('')存储数据,datetime也是,所有就添加单引号
                            value += info[i].Name + "='" + info[i].GetValue(model) + "'";
                        }
                        else
                        {
                            //因为字段不是单个,所以需要用,分割
                            value += info[i].Name + "='" + info[i].GetValue(model) + "',";
                        }
                    }
                }
            }
            string sql = $"update  {model.GetType().Name} set {value} where Id='{Id}'";
            return sql;
        }
        #endregion

        #region 添加
        public int Insert(T models)
        {
            int flag = 0;
            //获取sql
            string sql = GetInsertSql(models);
            using (SqlConnection connection = new SqlConnection(con))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    flag = command.ExecuteNonQuery();
                }
            }
            return flag;
        }
        public  string GetInsertSql(T models)
        {
            //已实例化的实体用GetType,如果未实例化的我们需要使用typeof
            Type type = models.GetType();//new 过的对象
            //获取所有的字段
            PropertyInfo[] info = type.GetProperties();
            //这里是字段
            string field = "";
            //获取值
            string value = "";
            //遍历所有的字段对象
            for (int i = 0; i < info.Length; i++)
            {
                //info[i].GetValue(models)获取某个字段的属性值
                //有可能字段没有值,没有值的我们不添加
                //info[i]是一个抽象类,存储着第几个字段的名称及类型等
                if (info[i].GetValue(models) != null)
                {
                        if (!info[i].Name.Contains("Id"))
                        //获取字段和值
                        if ((i + 1) == info.Length)//代表最后一个循环不要,
                        {
                            //info[i].Name代表某个字段的名称
                            field += info[i].Name;
                            //因为GetValue的参数是object所以不需要用类型判断
                            string name = info[i].GetValue(models).ToString();
                            value += "'" + info[i].GetValue(models).ToString() + "'";
                        }
                        else
                        {
                            field += info[i].Name + ",";
                            value += "'" + info[i].GetValue(models).ToString() + "',";
                        }
                }
            }
            //生成了sql语句
            string sql = "insert into " + type.Name + "(" + field + ") values(" + value + ")";
            return sql;
        }
        #endregion
        #region 删除语句
        public int Delete(T model)
        {
            string sql = GetDelete(model);
            int flag = 0;
            //数据库连接
            using(SqlConnection conn=new SqlConnection(con))
            {
                conn.Open();
                //实例化对象
                using (SqlCommand command=new SqlCommand(sql,conn))
                {
                    flag=command.ExecuteNonQuery();
                }
            }
            return flag;
        }
        public string GetDelete(T model)
        {
            string id = "";
            //删除和修改与添加基本无异
            Type type = model.GetType();
            PropertyInfo[] propertyInfo = type.GetProperties();
            for (int i = 0; i < propertyInfo.Length; i++)
            {
                if (propertyInfo[i].GetValue(model)!=null)
                {
                    if (propertyInfo[i].Name.Contains("Id"))
                    {
                        id += $"Id ={propertyInfo[i].GetValue(model)}";
                    }
                }
            }
            string sql = $"delete from {type.Name} where {id}";
            return sql;
        }
        #endregion
    }
}
DBHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}
Student
using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            DBHelper<Student> dBHelper = new DBHelper<Student>();
            List<Student> list= dBHelper.Query("");
            Console.WriteLine("查询语句:");
            Console.WriteLine("数据量为:"+list.Count);
            Console.WriteLine("添加语句:");
            Student student = new Student()
            {
                Id = 1,
                Name = "wxx"
            };
            dBHelper.Insert(student);
            Console.WriteLine("修改语句:");
            dBHelper.Update(student.Id, student);
            Console.WriteLine("修改语句执行成功!");
            Console.WriteLine("删除语句:");
            dBHelper.Delete(student);
            Console.WriteLine("删除成功!");
            Console.ReadKey();
        }
    }
}
Program

 

教大家一个小技巧:遇到没有用过的方法,接口,属性可以F12看看微软底层是如何解释的,当然微软底层是英文,可以利用翻译工具去翻译一下,看完一遍,仔细在自己脑袋里想几遍,要是还是不会,可以百度一下这个方法的用法.

一点点进步,一点点变优秀

转载于:https://blog.csdn.net/weixin_45978023/article/details/106780929

posted @ 2021-08-24 15:56  rookiexwang  阅读(96)  评论(0编辑  收藏  举报