///对字段特性的映射类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Attributes
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class FieldAttribute : Attribute
    {
        private string _Fields;
        /// <summary>
        /// 字段名称
        /// </summary>
        public string Fields
        {
            get { return _Fields; }

}

private DbType _Dbtype;
        /// <summary>
        /// 字段类型
        /// </summary>
        public DbType Dbtype
        {
            get { return _Dbtype; }

}

private int _ValueLength;
        /// <summary>
        /// 字段值长度
        /// </summary>
        public int ValueLength
        {
            get { return _ValueLength; }

}

private bool _PK_Primary;
        /// <summary>
        /// 是否是主键
        /// </summary>
        public bool PK_Primary
        {
            get { return _PK_Primary; }
        }

/// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fields"> 字段名</param>
        /// <param name="types"> 字段类型</param>
        /// <param name="i"> 字段值长度</param>
        public FieldAttribute(string fields, DbType types, int i,bool PK=false)
        {

_Fields = fields;
            _Dbtype = types;
            _PK_Primary = PK;
            _ValueLength = i;
        }
    }
}

///对表特性的映射类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Attributes
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class TableAttribute : Attribute
    {
        private string _TableName;
        /// <summary>
        /// 映射的表名
        /// </summary>
        public string TableName
        {
            get { return _TableName; }
        }
        /// <summary>
        /// 定位函数映射表名;
        /// </summary>
        /// <param name="table"></param>
        public TableAttribute(string table)
        {
            _TableName = table;
        }

}
}

公共方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
namespace Attributes
{
    /// <summary>
    /// 处理反射的类
    /// </summary>
    /// <typeparam name="T"> 与数据库表建立联系的类</typeparam>
    public class AttributesContext<T>
    {
        /// <summary>
        ///存放AttributesContext 类中所有的当前错误信息
        /// </summary>
        private string ExceptionBug;

/// <summary>
        /// 读取映射的表名
        /// </summary>
        /// <param name="Info">自定义类型</param>
        /// <returns>放回建立映射表名 没简历表面返回空</returns>
        public string xTable(T Info)
        {

Type userAttu = Info.GetType();
            try
            {
                TableAttribute tables = (TableAttribute)userAttu.GetCustomAttributes(false)[0];
                //在TableAttribute中我设置的是不容许多个特性所取 【0】
                return tables.TableName;
            }
            catch (ArgumentNullException e)
            {
                ExceptionBug = e.Message;
                return null;
            }
            catch (NotSupportedException e1)
            {
                ExceptionBug = e1.Message;
                return null;
            }

}

/// <summary>
        /// 放回自定义类与表建立的映射的字段名
        /// </summary>
        /// <param name="Info">与表建立映射联系的类</param>
        /// <returns>表字段的数组Dictionary   FieldAttribute ,Object[]| key 字段名 FieldAttribute ,value需要自己转换;object [2]  其中第一个是字段名称  第2个是字段值 </returns>
        public Dictionary<FieldAttribute, Object[]> xField(T Info)
        {
            Dictionary<FieldAttribute, Object[]> xFields = new Dictionary<FieldAttribute, Object[]>();
          
            Type types = Info.GetType();
            PropertyInfo[] typesPro = types.GetProperties();

foreach (PropertyInfo pro in typesPro)
            {
                object[] attu = pro.GetCustomAttributes(false);

object objValue = pro.GetGetMethod().Invoke(Info, null);//取特性描述相应字段的值
                object objFieldName = (Object)pro.Name;//取特性对应类的字段名称
                object[] classInfo = new object[2];//把类中的字段名称与值存放;
               
                classInfo[0] = objFieldName;
                classInfo[1] = objValue;

foreach (Attribute afield in attu)
               {
                   if (afield is FieldAttribute)
                   {
                       FieldAttribute column = afield as FieldAttribute;//把afield转换成FieldAttribute类型
                       xFields.Add(column, classInfo);//把字段存放到key 把特性描述的字段字存放到value
                   
                   }
                   
               }

}

return xFields;
        }

}
}

用AttributesContext中的  public Dictionary<FieldAttribute, Object[]> xField(T Info)
我们可以获得字段与特性以及值的Dictionary   当我们知道 Dictionary就可以取出相应的信息让后我们在拼接一下 就可以获得命令语句;

我写得是拼接的字符串下面是列子;

/// <summary>
    /// 用来拼接操作数据库的字符串
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Install<T>
    {
        /// <summary>
        /// 拼接查询字符串(只能用在与表建立联系的实体类)
        /// </summary>
        /// <param name="types"> 与表建立映射的自定义类</param>
        /// <returns>查询字符串</returns>
        public string insertDate(T types)
        {
            string cmdtxt = "insert into ";
            string cmdparVar = null;
            Type userAttu = types.GetType();
            TableAttribute  tables = (TableAttribute )userAttu.GetCustomAttributes(false)[0];
            cmdtxt += tables.TableName + "(";
            PropertyInfo[] info = userAttu.GetProperties();

foreach (PropertyInfo prs in info)
            {
                object[] attu = prs.GetCustomAttributes(false);

foreach (Attribute abute in attu)
                {
                    if (abute is FieldAttribute)
                    {
                        FieldAttribute midle = abute as FieldAttribute;
                         cmdtxt +=  midle.Fields + ",";
                         object obj = prs.GetGetMethod().Invoke(types,null);
                        if (midle.Dbtype == DbType.Int32)
                            cmdparVar +=  obj + ",";
                        else
                            cmdparVar+="'"+obj +"',";
                      
                    }
                }
               
            }

cmdparVar = cmdparVar.Substring(0, cmdparVar.Length - 1);
            cmdtxt = cmdtxt.Substring(0, cmdtxt.Length - 1) + ")";

cmdtxt += "values(" + cmdparVar + ")";
            return cmdtxt;
        }

同理我们可以拼接出其他语句; 这只是思路 我还没优化以及错误处理; 还可以改进 改为参数化查询 在特性中不是有类型 字段长度的嘛!那我们就可以利用参数化列;

下面是我写的自动创建参数化对象

/// <summary>
        /// 创建存储过程的参数  只用于 (SQL语法)
        /// </summary>
        /// <param name="parName">参数名(与存储过程参数名一样)</param>
        /// <param name="parType">参数的数据类型</param>
        /// <param name="parSize">参数字段长度 int 用0表示长度</param>
        /// <param name="parVal">输入参数的值</param>
        /// <param name="aspect">传入方式</param>
        /// <returns></returns>

public static SqlParameter CreateProcParameters(string parName, SqlDbType parType, int parSize, object parVal, ParameterDirection aspect = ParameterDirection.Input)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = parName;
            p.SqlDbType = parType;
            p.Direction = aspect;
            if (parSize != 0)
                p.Size = parSize;
            p.SqlValue = parVal;
            return p;
        }

循环添加参数到命令中

public static void AddParametersTocmd(SqlCommand cmd,params SqlParameter[] pList)
        {
            foreach (SqlParameter s in pList)
            {
                cmd.Parameters.Add(s);//添加参数
            }
        }

下次有时候在把完整的实现表与类的映射实现自动化增删改查些出来; 我也才开始学习哪些对象我也只是猜实现 还没进行优化所以等下次我 我在发表;

转载于:https://www.cnblogs.com/aw25220/archive/2011/04/24/2026561.html

c#利用反射+特性实现简单的实体映射数据库操作类实现自动增删改查(一)相关推荐

  1. c#利用反射+特性实现简单的实体映射数据库操作类(表与类的映射)

    开始之前首先需要了解 特性Attribute; 说穿了特性也就是一些声明信息:我们在运行的时候可以用反射获取这些声明: 所想我们试想下:我们新建一个类用来存放数据库表中的信息: 那我们是不是需要在该类 ...

  2. 利用DB Link搞定Oracle两个数据库间的表同步

    数据库之间的链接建立在DATABASE LINK上.要创建一个DB LINK,必须先 在每个数据库服务器上设置链接字符串. 1. 链接字符串即服务名,首先在本地配置一个服务名,地址指向远程的数据库地址 ...

  3. 利用反射动态修改 EasyPoi 导出Excel表格标题名称

    EasyPoi 动态修改表格标题名称 需求 代码实现 1.实体类 @Data @Accessors(chain = true) public class AccountVO implements Se ...

  4. 数据库的三级模式和两级映射--简单介绍

    形象解释数据库的三级模式和两级映射 数据库的三级模式和两级映射是美国国家标准协会(American National Standard Institute, ANSI)的数据库管理系统研究小组于197 ...

  5. CN.Text开发笔记—利用反射将数据读入实体类

    在实际开发中,我们经常需要从数据库中读取数据并赋值给实体类的相应属性.在.Text的DataDTOProvider中存在大量这样的代码, 比如: public Role[] GetRoles(int  ...

  6. golang利用反射写入excel的简单工具类

    golang利用反射写入excel的简单工具类 工具类源码 使用方法 工具类源码 package excelimport ("errors""github.com/tea ...

  7. mvc4 利用filters特性来 实现自己的权限验证 之二

    刚开始摸索C# MVC,也只是按图索骥,对C#的特性不是很懂,耐心看完相关文章,对特性的使用有了进一步理解. 1.特性类的命名规范:特性也是一个类,必须继承于System.Attribute类,命名规 ...

  8. 第六节:反射(几种写法、好处和弊端、利用反射实现IOC)

    一. 加载dll,读取相关信息 1. 加载程序集的三种方式 调用Assembly类下的三个方法:Load.LoadFile.LoadFrom. 1 //1.1 Load方法:动态默认加载当前路径下的( ...

  9. 利用反射,批量启动WCF服务

    对于WCF的宿主启动来说,有好多方法,单独启动也很简单,可以根据业务需要来自由选择(单独启动方法这里就不做解释) 对于业务服务比较多的时候,往往需要多个服务来承载系统,但是如果将服务启动单独写代码启动 ...

最新文章

  1. 免费教材丨第48期:业界大牛中文教学视频《深度学习:进阶》第25-28讲
  2. es java match_ES multi_match 和match查询
  3. java 检查pos机状态_POS机故障大全及排查方法
  4. 【2012百度之星/资格赛】J:百度的新大厦
  5. Django框架(三)—— orm增删改查、Django生命周期
  6. 决定将本博客技术知识从VS.Net转型SuperMap产品动态与开发
  7. 网络技巧:分享几个路由器设置小技巧,总有用得到的一天!
  8. 数据结构杂谈(五)——栈
  9. 【POJ - 1087】A Plug for UNIX(建图,网络流最大流)
  10. 提高tomcat的并发能力
  11. [置顶]android ListView包含Checkbox滑动时状态改变
  12. 对话图灵奖得主、CNN之父Yann LeCun:我在中国看到了AI研究热潮
  13. OPPO 人像视频黑科技新鲜出炉,下月就换手机!
  14. linux --- TCPdump 工具
  15. Unity3D实践2:控制物体移动与旋转
  16. 【20171227】json
  17. 小记三款SD卡速度测试
  18. JavaScript练习题
  19. 类的继承------C++
  20. 【WPS自动签到】利用云函数实现WPS自动签到获得WPS免费会员

热门文章

  1. 前端html5CSS3颜色表示法
  2. C#学生信息管理系统
  3. php在一定范围内去随机整数,php-如何从随机位生成范围内的整数
  4. React学习:路由定义及传参、数据复用-学习笔记
  5. node服务:日志、配置、路由与控制器
  6. dojo中的dojo/dom-class
  7. GitHub for Windows使用教程(二) 分支的使用
  8. Redis 热 Key 发现以及解决办法
  9. 基于SSD的Kafka应用层缓存架构设计与实现
  10. Scala Hbase 问题汇总