zoukankan      html  css  js  c++  java
  • C#反射在数据库操作中的应用(反射属性,反射字段)

    这几天学习反射的应用,今天把其应用到数据操作中

    现记录学习笔记

    环境为:

      编译器:vs2017

      数据库:access

      反射类型为:字段

    1先在类文件的定义是用哪种数据库,和用字段还是属性来反射

    本例是:Access数据库+反射字段

    #define OLEDB_  //access数据库
    #define FIELDS_  //反射字段

    2.定义数据库操作类的别名,用来区分数据库操作要用的函数

    定义是反射的是字段还是反射的是属性

        //区分是用哪种数据库
    #if OLEDB_  //access
        using MyConnection = OleDbConnection;
        using MyCommand = OleDbCommand;
        using MyDataAdapter = OleDbDataAdapter;
        using MyCommandBuilder = OleDbCommandBuilder;
        using MyParameter = OleDbParameter;
        using MyDataRead = OleDbDataReader;
        //...
    #elif SQL_  //sql
        using MyCommand = SqlCommand;
        using MyConnectin = SqlConnection;
        using MyDataAdapter = SqlDataAdapter;
        using MyCommandBuilder = SqlCommandBuilder;
        using MyParameter = SqlParameter;
        using MyDataRead = SqlDataReader;
        //....
    
    #endif
    
    
            //区分是用类的字段还是类的属性,
    #if FIELDS_
        using MyInfo = FieldInfo;//字段
    #elif POPRS_
        using MyInfo = PropertyInfo;//属性
    
    #endif
    

      

    3.在类中定义方法来选择反射的样式

    //单表模板操作类

    //T 为和数据库中要操作的表一样的类或结构体

    //可以反射属性,也可以反射字段

    class BDAdo<T>

    {

        /// <summary>
            /// 获得属性列表,或是字段列表
            /// </summary>
            /// <returns></returns>
            private MyInfo[] GetInfos()
            {
    #if FIELDS_ //字段
                return typeof(T).GetFields();
    #elif POPRS_    //属性
                return typeof(T).GetProperties();
    #endif
            }

    }

    下面就是在类的各种操作的实现

    4.获得查询结果的表

            /// <summary>
            /// 查询指定条件的列表数据
            /// </summary>
            /// <param name="findsql"> 指定查询条件,为NULL就查询全部数据</param>
            /// <returns></returns>
            public DataTable GetDataTable(string findsql = null)//查询条件字符串,也就是Sql语句查询的 where 后面的条件语句
            {
                Type ty = typeof(T);
                // string fName = string.Join(",", ty.GetFields().Select(p => p.Name));
                string sql = $"select * from [{ty.Name}]";
                if (findsql != null)
                    sql += $" where {findsql}";
    
                DataTable dt = new DataTable();
                conn = new MyConnection(conStr);
                MyDataAdapter da = new MyDataAdapter(sql, conn);
    
                try
                {
                    da.Fill(dt);
                    return dt;
                }
                finally
                {
                    conn.Close();
                    da.Dispose();
                }
            }

    5.添加数据

    /// <summary>
            /// 插入数据
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            /// <returns></returns>
            public bool InsertData(T t)
            {
                //获得对象的类型
                Type ty = t.GetType();
    
                //拼接添加数据的Sql语句
                string intoSql = $"INSERT INTO [{ty.Name}] ({GetFildeNames()}) VALUES ({GetFileParams()})";
    
                conn = new MyConnection(conStr);
                MyCommand cmd = conn.CreateCommand();
                cmd.CommandText = intoSql;
                cmd.Parameters.AddRange(GetParameters(t));
    
                try
                {
                    conn.Open();
                    return cmd.ExecuteNonQuery() == 1;
                }
                finally
                {
                    cmd.Dispose();
                    conn.Close();
                }
            }

    6 根据字段或是属性获得参数化列表

            /// <summary>
            /// 获得参数化列表
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            /// <returns></returns>
            private MyParameter[] GetParameters(T t)
            {
                Type ty = typeof(T);
                List<MyParameter> parList = new List<MyParameter>();
                foreach (var v in GetInfos())
                {
                    MyParameter pr = new MyParameter($"@{v.Name}", v.GetValue(t));
                    parList.Add(pr);
                }
                return parList.ToArray();
            }

    7.获得字段或是属性名称组成的字符串

     /// <summary>
            /// 获得类的字段名或属性名,组成的字符串
            /// </summary>
            /// <param name="ty"></param>
            /// <returns></returns>
            private string GetFildeNames()
            {
                Type ty = typeof(T);
                return string.Join(",", GetInfos().Select(p => $"[{p.Name}]"));
            }

    样式:
    name,sex,age,tel,adds

    8.获得字段或是属性名称组成的参数格式字符串

     /// <summary>
            /// 获得类的字段名或是属性名,并以参数化样式(@name)组成的字符串
            /// </summary>
            /// <param name="ty"></param>
            /// <returns></returns>      
            private string GetFileParams()
            {
                Type ty = typeof(T);
                return string.Join(",", GetInfos().Select(p => $"@{p.Name}"));
            }
    //样式:
    @name,@sex,@age,@tel,@adds

    9.对数据库的增,删,改,执行命令

    1可以是Sql语句操作,

    2也可以是参数化列表操作,

    3也可以是储存过程操作

    /// <summary>
           /// Sql语句执行命令(insert,delete,update)
           /// </summary>
           /// <param name="sql"></param>
           /// <param name="cmdType"></param>
           /// <param name="pars"></param>
           /// <returns></returns>
            public int ExecuteNonQuery(string sql, CommandType cmdType = CommandType.Text,
                params MyParameter[] pars)
            {
                conn = new MyConnection(conStr);
    
                MyCommand cmd = conn.CreateCommand();
                cmd.CommandType = cmdType;
                cmd.CommandText = sql;
                if (pars.Length > 0)
                {
                    cmd.Parameters.Clear();
                    cmd.Parameters.AddRange(pars);
                }
    
                try
                {
                    conn.Open();
                    return cmd.ExecuteNonQuery();
                }
                finally
                {
                    conn.Close();
                    cmd.Dispose();
                }
            }

    10.查询指定条件,返回一个对象实例

     /// <summary>
            /// 查询指定条件的对象
            /// </summary>
            /// <param name="cxSql"></param>
            /// <returns></returns>
            public T FindOneObject(string cxSql)
            {
                Type ty = typeof(T);
                //string sql = $"select {GetFildeNames()} from {ty.Name} where {cxSql}";
                object obj = Activator.CreateInstance(ty);
                DataTable dt = GetDataTable(cxSql);
                if (dt.Rows.Count == 0)
                    return default(T);
    
                foreach (var v in GetInfos())
                {
    
                    SetObjectValue(v, dt.Rows[0][$"{v.Name}"], ref obj);
                }
                return (T)obj;
            }

    SetObjectValue()

            /// <summary>
            /// 设置字段或是属性相应的值
            /// </summary>
            /// <param name="v">属性或是字段</param>
            /// <param name="value">要设置的值</param>
            /// <param name="obj">要设置的对象</param>
            private void SetObjectValue(MyInfo v, object value, ref object obj)
            {
                string name =null;//获得字段或是属性的数据类型名称,用来给相应的数据类型赋值
    #if POPRS_  //属性
                name = v.PropertyType.Name;
    #elif FIELDS_ //字段
                name=v.FieldType.Name;
    #endif
                switch (name)
                {
                    case "Int32": //int
                        v.SetValue(obj, int.Parse(value.ToString()));
                        break; ;
    
                    case "String":  //string
                        v.SetValue(obj, value.ToString());
                        break;
    
                    case "Double":  //double
                        v.SetValue(obj, double.Parse(value.ToString()));
                        break;
    
                    case "Object"://object
                        v.SetValue(obj, value);
                        break;
    
                    case "Boolean"://bool
                        v.SetValue(obj, bool.Parse(value.ToString()));
                        break;
    
                    case "Char"://char
                        v.SetValue(obj, char.Parse(value.ToString()));
                        break;
    
                    case "Byte[]"://byte[]
                        if(value!=DBNull.Value)
                            v.SetValue(obj, (byte[])value);//强转为字节数组
                        break;
    
                    default: //其他类型,以后用的时候再加上
                        throw new Exception("没有指定转换的类型!!!");
    
    
                }
            }

    11.用法

    在要用的类中声明一个静态对象

    public class MyApp 
    {
      public static BDAdo<TXL_TABLE> Ado { get => new BDAdo<TXL_TABLE>();/* set => ado = value;*/ }
    }

    示例1:添加数据

    TXL_TABLE tt = new TXL_TABLE();
                tt.ID = int.Parse(txtID.Text);
                tt.TName = txtName.Text;
                tt.Sex = txtSex.Text;
                tt.Age=int.Parse(txtAge.Text);
                tt.FenZu = txtFenZu.Text;
                tt.Tel = txtTel.Text;
                byte[] tem = { 0 };
                if (picImage.Image != null)
                    tt.Image = MyApp.Ado.ImageToByte(picImage.Image);
                else
                    tt.Image = tem;
    
                bool bRet = MyApp.Ado.InsertData(tt);
                if(bRet)
                {
                        MessageBox.Show("添加成功")
                }

    示例2:修改数据

    TXL_TABLE tt = new TXL_TABLE();
                tt.ID = int.Parse(txtID.Text);
                tt.TName = txtName.Text;
                tt.Sex = txtSex.Text;
                tt.Age=int.Parse(txtAge.Text);
                tt.FenZu = txtFenZu.Text;
                tt.Tel = txtTel.Text;
                byte[] tem = { 0 };
                if (picImage.Image != null)
                    tt.Image = MyApp.Ado.ImageToByte(picImage.Image);
                else
                    tt.Image = tem;
    
                 if( MyApp.Ado.UpdateData($"ID={oldID}", tt)>0)
                        MessageBox.Show("修改成功");

    示例3:查找单个对象

     int id = (int)Tag;
                   TXL_TABLE tt= MyApp.Ado.FindOneObject($"ID={id}");

    //......

    签名:GreenLeaf1976
  • 相关阅读:
    后台菜单权限设计实现思路
    Laravel创建模型到指定目录
    laravel框架加载静态资源注意事项
    mysql 快速生成测试数据小技巧
    Lavaral基础实践——文件上传报错
    PHP常量详解:define和const的区别
    开发常用的工具网站
    windows下用navicat远程链接虚拟机Linux下MySQL数据库(测试可行)
    java异常处理机制思路总结
    记录一些比较容易含糊的概念
  • 原文地址:https://www.cnblogs.com/greenleaf1976/p/15055991.html
Copyright © 2011-2022 走看看