zoukankan      html  css  js  c++  java
  • 自己写Facotry解析.Net 的反射和attribute

    很多人都知道工厂,知道反射,但是真正能用的好的并不多,我也是最近才真正明白了什么是反射,反射和.Net 里的一些其他特性是怎么应用的。在这里,分享一个自己写的小的数据库工厂的架构,和大家讨论。

    目的的需求

    在一个系统里,需要有一个统一的数据库类实现对SQL Server的增删改查 ,要求有良好的扩展行和维护性。

    在知道反射和属性之前的思路,是对每个实体类写相应的操作。但是现在,可以通过应用Attribute来进行自己定义

    首先,要把数据库里的表和实体类对应.这样,我们简单的定义一个属性ClassesDefineSqlAttribute,用对应表和实体类。

     

    [AttributeUsage(AttributeTargets.Class)]
        
    class ClassesDefineSqlAttribute :Attribute 
        {
            
    public String SqlTableName { getset; }
            
    public ClassesDefineSqlAttribute()
            {
              
            }

        }

     

    第一步对应好了以后,下一步要将实体类的属性与数据库表中的列进行对应,为此,定义 ClassesDefineColumnAttribute 这里,只是简单的设置了列名,列的类型(数据,主键,改之前的主键),呵呵,一切从简,够用就好

     

        public enum ColType
        {
            
    /// <summary>
            
    /// 数据列
            
    /// </summary>
            Data,
            
    /// <summary>
            
    /// 主键列
            
    /// </summary>
            ClassCode,
            
    /// <summary>
            
    /// 级别列(在树型结构中用到)
            
    /// </summary>
            ClassLevel,
            
    /// <summary>
            
    /// 旧键(更新时使用)
            
    /// </summary>
            OldCode
        }
        [AttributeUsage(AttributeTargets.Property )]
        
    public class ClassesDefineColumnAttribute:Attribute 
        {
            
    //对应的数据库列名
            public string SqlColName { getset; }
            
    /// <summary>
            
    /// 列的类型
            
    /// </summary>
            public ColType ColType { getset; }


            
    /// <summary>
            
    /// 复杂类型的属性值 
            
    /// </summary>
            public string TargetProperty { getset; }
          
        }
    }

     

     

    用了这些准备,就可以在数据工厂中完成增删改查了

    为了通用,我们把增删改的参数都设置成object  ,这样,在操作时,先将object 的最终类别取到,然后得到上面的几个属性,动态的生成SQL语句

    先看增操作

     

            public void Create(object T)
            {
                var info 
    = T.GetType();//得到要新建的类型
                ClassesDefineSqlAttribute attribute =
                    (ClassesDefineSqlAttribute)Attribute.GetCustomAttribute(info,
                    
    typeof(ClassesDefineSqlAttribute));///得到表名


                
    if (attribute != null)
                {

                    var Properties 
    = info.GetProperties();///得到属性
                    System.Reflection.PropertyInfo KeyProperty = null;
                    String insert 
    = "INSERT " + attribute.SqlTableName + "(";
                    String values 
    = ") Values(";
                    String checksql 
    = "";

                    String GetKeySql 
    = "WHERE 1=1";

     
                    
    foreach (var infoattr in Properties)
                    {
                         
                        var ob 
    = Attribute.GetCustomAttribute(infoattr, typeof(ClassesDefineColumnAttribute));

                        
    if (ob != null)
                        {
                            var attr 
    = ob as ClassesDefineColumnAttribute;

                            
    if (attr is ClassesDefineColumnAttribute)
                            {


                                var a 
    = attr as ClassesDefineColumnAttribute;
                                
    if (a.ColType != ColType.OldCode)
                                {


                                    
    if (a.ColType != ColType.ClassCode
                                       
    ||
                                        infoattr.PropertyType 
    == typeof(String))
                                    {

                                        
    string valuestr = (infoattr.GetValue(T, null?? "").ToString();
                                        insert 
    += a.SqlColName + ",";
                                        values 
    += "'" + valuestr + "',";
                                        GetKeySql 
    = GetKeySql + " And " + a.SqlColName + "='" + valuestr + "'";
                                    }
                                    
    if (a.ColType == ColType.ClassCode)
                                    {

                                        KeyProperty 
    = infoattr;
                                        
    if (KeyProperty.PropertyType == typeof(String))
                                        {

                                            checksql 
    = "Select Count(*) FROM " + attribute.SqlTableName + " Where " + a.SqlColName + "='" + (infoattr.GetValue(T, null?? "").ToString() + "'";
                                            
    if (System.Convert.ToInt32(
                                                
    new DataConnectionFactory().GetDataTable(checksql).Rows[0][0]) > 0)
                                                
    throw new Exception("无法生成新数据,与现有数据编码相同!");
                                        }
                                        
    else
                                        {
                                            GetKeySql 
    = "Select " + a.SqlColName + " FROM " + attribute.SqlTableName + " " + GetKeySql;
                                        }
                                    }



                                }
                            }



                        }
                    }
                   
                    String sql 
    = insert.Substring(0, insert.Length - 1+ values.Substring(0, values.Length - 1+ ")";

                    
    using (var db = new DataConnectionFactory().GetConnection())
                    {
                        db.ExecuteCommand(sql);


                        
    //设置 自增长主键的返回直

                        
    if (KeyProperty.PropertyType != typeof(string))
                        {
                            KeyProperty.SetValue(T,
                                
    new DataConnectionFactory().GetDataTable(GetKeySql).Rows[0][0], null);
                        }

                    }



                }
                
    else
                {
                    
    throw new Exception("类型不符合要求");
                }

            }

    增操作完成,改的操作也很类似

     

            public void Save(object T)
            {
                var info 
    = T.GetType();
                ClassesDefineSqlAttribute attribute 
    = (ClassesDefineSqlAttribute)Attribute.GetCustomAttribute(info, typeof(ClassesDefineSqlAttribute));
                String oldCode 
    = "";
                String newCode 
    = "";


                
    bool HaveOldCode = false;

     
                System.Reflection.PropertyInfo KeyProperty 
    = null;

                
    if (attribute != null)
                {

                    var Properties 
    = info.GetProperties();
                    String insert 
    = "UPDATE " + attribute.SqlTableName + " SET ";
                    String wheresql 
    = "";

                    String checksql 
    = "";

                    
    foreach (var infoattr in Properties)
                    {
                       
                        var ob 
    = Attribute.GetCustomAttribute(infoattr, typeof(ClassesDefineColumnAttribute));

                        
    if (ob != null)
                        {
                            var attr 
    = ob as ClassesDefineColumnAttribute;
                            
    if (attr is ClassesDefineColumnAttribute)
                            {
                                var valueStr 
    = infoattr.GetValue(T, null).ToString();

                                var a 
    = attr as ClassesDefineColumnAttribute;
                                
    if (attr.ColType == ColType.Data
                                    
    || (attr.ColType == ColType.ClassCode && infoattr.PropertyType == typeof(String)))
                                    insert 
    += a.SqlColName + "='" + valueStr + "',";

                                
    if (a.ColType == ColType.ClassCode)
                                {
                                    checksql 
    = a.SqlColName + "='" + valueStr + "'";
                                    KeyProperty 
    = infoattr;
                                    newCode 
    = valueStr;
                                }
                                
    if (a.ColType == ColType.OldCode)
                                {
                                    HaveOldCode 
    = true;
                                    wheresql 
    = " Where " + a.SqlColName + "='" + valueStr + "'";
                                    oldCode 
    = valueStr;

                                }
                            }



                        }
                    }

                   

                    
    if (HaveOldCode)
                    {
                        
    if (newCode != oldCode)
                        {

                            checksql 
    = "Select count(*) FROM " + attribute.SqlTableName + wheresql + " OR  " + checksql;

                            
    if (System.Convert.ToInt32(
                                
    new DataConnectionFactory().GetDataTable(checksql).Rows[0][0]) >= 2)
                                
    throw new Exception("无法生成新数据,与现有数据编码相同!");
                        }
                    }
                    
    else
                        wheresql 
    = "Where " + checksql;
                    String sql 
    = insert.Substring(0, insert.Length - 1+ wheresql;
                    
    using (var db = new DataConnectionFactory().GetConnection())
                    {
                        db.ExecuteCommand(sql);
                    }



                }
                
    else
                {
                    
    throw new Exception("类型不符合要求");
                }


            }

    最后是删除的操作

     

         public void Delete(object T)
            {
                var info 
    = T.GetType();
                ClassesDefineSqlAttribute attribute 
    = (ClassesDefineSqlAttribute)Attribute.GetCustomAttribute(info, typeof(ClassesDefineSqlAttribute));
                TreeNodeAttribute treedef 
    = (TreeNodeAttribute)Attribute.GetCustomAttribute(info, typeof(TreeNodeAttribute));
           

                
    if (attribute != null)
                {

                    var Properties 
    = info.GetProperties();
                    String insert 
    = "Delete " + attribute.SqlTableName + " ";
                    

                    
    foreach (var infoattr in Properties)
                    {                     var ob 
    = Attribute.GetCustomAttribute(infoattr, typeof(ClassesDefineColumnAttribute));

                        
    if (ob != null)
                        {
                            var attr 
    = ob as ClassesDefineColumnAttribute;
                            
    if (attr is ClassesDefineColumnAttribute)
                            {
                                var valueStr 
    = infoattr.GetValue(T, null).ToString();

                                var a 
    = attr as ClassesDefineColumnAttribute;
                               
                                
    if (a.ColType == ColType.OldCode)
                                {

                                    insert  
    += " Where " + a.SqlColName + "='" + valueStr + "'";

                                    
    break;

                                }
                                
    else if (a.ColType == ColType.ClassCode)
                                {
                                    insert 
    += " Where " + a.SqlColName + "='" + valueStr + "'";

                                    
    break;
                                }
                            }



                        }
                    }
                    String sql 
    = insert;

              
                    
    using (var db = new DataConnectionFactory().GetConnection())
                    {
                        db.ExecuteCommand(sql);
                    }



                }
                
    else
                {
                    
    throw new Exception("类型不符合要求");
                }


            }

     

    这样,再有类型 ,只要做好相应的标记,便 可直接应用这个类了

    如我的表示档案盒的类型FileBox

        [ClassesDefineSql(SqlTableName = "DA_FileBox")]
        
    public class FileBox
        {
            
    /// <summary>
            
    /// 档案盒
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.ClassCode, SqlColName = "BoxNo")]
            
    public String BoxNo
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 标签ID
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.Data, SqlColName = "TagNo")]
            
    public string TagID
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 类别信息
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.Data, SqlColName = "ClassNo")]
            
    public string ClassNo
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 类别名称
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.Data, SqlColName = "ClassName")]
            
    public string ClassName
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 位置编号
            
    /// </summary>

            [ClassesDefineColumn(ColType 
    = ColType.Data, SqlColName = "LocationNo")]
            
    public string LocationNo
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 位置说明
            
    /// </summary>

            [ClassesDefineColumn(ColType 
    = ColType.Data, SqlColName = "LocationName")]
            
    public string LocationName
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 备用一
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.Data, SqlColName = "Note1")]
            
    public string Note1
            {
                
    get;
                
    set;
            }

            
    /// <summary>
            
    /// 备用二
            
    /// </summary>
            [ClassesDefineColumn(ColType = ColType.Data, SqlColName = "Note2")]
            
    public string Note2
            {
                
    get;
                
    set;
            }
        }
  • 相关阅读:
    内存使用过高点检checklist
    Ubuntu linux系统下 su:出现: authentication failure的解决办法
    static完全解析
    C语言开发规范
    单片机、ARM、PC程序执行介质区别
    2021来了,一份小菜鸡的2020总结!
    Linux命令进阶篇-文件查看与查找
    LINUX常用命令(二)
    Linux常用命令(一)
    百钱百鸡
  • 原文地址:https://www.cnblogs.com/geyunfei/p/2001952.html
Copyright © 2011-2022 走看看