• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#编写框架

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

今天在这里写一套简单的框架,主要用于一些小型的项目,用于数据的增删改查,通用分页查询等操作.所以功能并不强大,而且笔者也是新手,这里面也难免会有bug,忘读者朋友提醒.

现在我们进入正题吧,想要写一套通用的框架,反射是必须要熟知的.至少你需要知道如何通过反射获取属性和值.然后我们自定义一些特性,用于和数据库的连接.

完成框架的制作,我们分步骤来说

1.编写自定义特性

2.通过发射,拼接字符串,用于数据操作

3.完善框架

 

好,我们先编写自定义特性,创建2.0(因为2.0可以向上兼容,为了实现通用,习惯使用4.0的朋友们,辛苦你们一下了)类库,我的项目名称为ORMAttributes,创建完成之后,我们创建我们的特性,添加cs文件,取名为AttributeTF

这个类需要继承Attribute,首先我们创建特性BindTableAttribute,用于标识类与数据库表之间的关系

 1  /// <summary>
 2         /// 表特性
 3         /// </summary>
 4         /// 特性用于class类,一个类中使用只能出现一次
 5         /// 
 6         [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
 7         public class BindTableAttribute : Attribute
 8         {
 9             public BindTableAttribute()
10                 : base()
11             {
12 
13             }
14 
15             public BindTableAttribute(string name,Type t)
16             {
17                 _name = name;
18                 _ct = t;
19 
20                 new TabelInfo(name,t,ColAdd);
21             }
22 
23             private Type _ct;
24 
25             public Type Ct
26             {
27                 get { return _ct; }
28                 set { _ct = value; }
29             }
30 
31             private string _name = null;
32             public string name
33             {
34                 get { return _name; }
35             }
36 
37             private bool _colAdd = false;
38             public bool ColAdd
39             {
40                 get { return _colAdd; }
41                 set { _colAdd = value;
42                 ManageTabel._tabels[_name].ColAdd = value;
43                 }
44             }
45         }
View Code

_ct:使用记录当前这个类的实体(其实可以不使用,具体原因我后面会说到)

_name:记录名称,也就是用于对应的数据库表名称

_colAdd:是否自动添加列(这是一个辅助的功能,主要用于实体类添加字段后,对应的数据库中是否同样添加列)

接着我们创建BindFiledAttribute,用于标识属性与数据库表中列之间的关系

 1   /// <summary>
 2         /// 类特性
 3         /// </summary>
 4         /// 特性作用于属性/字段上.且只能出现一次
 5         [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
 6         public class BindFiledAttribute : Attribute
 7         {
 8             public BindFiledAttribute()
 9                 : base()
10             {
11 
12             }
13 
14             public BindFiledAttribute(string name)
15             {
16                 _strName = name;
17             }
18 
19             private string _strName = null;
20 
21             public string StrName
22             {
23                 get { return _strName; }
24             }
25 
26 
27             private string _type = null;
28 
29             public string Type
30             {
31                 get { return _type; }
32                 set { _type = value; }
33             }
34 
35             private string _readFormat = null;
36 
37             public string ReadFormat
38             {
39                 get { return _readFormat; }
40                 set { _readFormat = value; }
41             }
42 
43             private string _writeFormat = null;
44 
45             public string WriteFormat
46             {
47                 get { return _writeFormat; }
48                 set { _writeFormat = value; }
49             }
50 
51             private int _index = -1;
52 
53             public int Index
54             {
55                 get { return _index; }
56                 set { _index = value; }
57             }
58 
59             private bool _isKey = false;
60 
61             public bool IsKey
62             {
63                 get { return _isKey; }
64                 set { _isKey = value;
65                 }
66             }
67 
68             private bool _isIdentity = false;
69 
70             public bool IsIdentity
71             {
72                 get { return _isIdentity; }
73                 set { _isIdentity = value; }
74             }
75 
76         }
View Code

_strName:表示列的名称

_type:数据类型,例如:varchar(100)...

_readFormat:读取时样式(这个不用在意,笔者发现,这个完全可以返回由程序员自己完成,意义不大)

_writeFormat:保存时样式(同上)

_index:序列号,新增时比较实用,同样可以提高效率(笔者解决了新增时顺序的问题,后面有详细介绍)

_isKey:是否是主键列

is_IsIdentity:是否为自动增涨列

ok,,这样我们的自定义特性也就完成了,,下面我们在model层的实体类上标识下我们所写的特性吧

 1 [BindTableAttribute("MyFromWork", typeof(MyFromWork), ColAdd = true)]
 2     public class MyFromWork {
 3         private int _id;
 4         [BindFiledAttribute("id",IsIdentity=true, IsKey = true, Type = "int")]
 5         public int Id
 6         {
 7             get { return _id; }
 8             set { _id = value; }
 9         }
10         
11         private string _name;
12         [BindFiledAttribute("name", Type = "varchar(50)")]
13         public string Name
14         {
15             get { return _name; }
16             set { _name = value; }
17         }
18 
19         private string _author;
20 
21         [BindFiledAttribute("author", Type = "varchar(50)")]
22         public string Author
23         {
24             get { return _author; }
25             set { _author = value; }
26         }
27 
28         private string _remarks;
29         [BindFiledAttribute("remarks", Type = "nvarchar(500)")]
30         public string Remarks
31         {
32             get { return _remarks; }
33             set { _remarks = value; }
34         }
View Code

怎么样,是不是很轻松呢,好,我们继续向下说

特性已经出现了,那么我们必定需要有一个地方来存储我们所标识的实体对应的值,所以笔者在这定义了TabelInfo和FileInfo,分别来记录BindTableAttribute和BindFiledAttribute.

  public class FileInfo
    {
        public FileInfo() : base() { }

        /// <summary>
        /// 字段名
        /// </summary>
        private string _strName;

        public string StrName
        {
            get { return _strName; }
            set { _strName = value; }
        }

        /// <summary>
        /// 数据类型(数据库中)
        /// </summary>
        private string _type;

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        /// <summary>
        /// 展现时字符串样式
        /// </summary>
        private string _readFormat;

        public string ReadFormat
        {
            get { return _readFormat; }
            set { _readFormat = value; }
        }

        /// <summary>
        /// 保存时字符格式
        /// </summary>
        private string _writeFormat;

        public string WriteFormat
        {
            get { return _writeFormat; }
            set { _writeFormat = value; }
        }

        /// <summary>
        /// 序列号
        /// </summary>
        private int _index=-1;

        public int Index
        {
            get { return _index; }
            set { _index = value; }
        }

        /// <summary>
        /// 是否作为条件使用
        /// </summary>
        private bool _isKey;

        public bool IsKey
        {
            get { return _isKey; }
            set { _isKey = value; }
        }

        /// <summary>
        /// 是否为自动增涨列
        /// </summary>
        private bool _isIdentity;

        public bool IsIdentity
        {
            get { return _isIdentity; }
            set { _isIdentity = value; }
        }
View Code
  public class TabelInfo
    {   #region 属性
        //表名
        private string _tabelName;

        public string TabelName
        {
            get { return _tabelName; }
            set { _tabelName = value; }
        }

        private Type _type;

        public Type TabelType
        {
            get { return _type; }
            set { _type = value; }
        }

        /// <summary>
        /// 字段特性
        /// </summary>
        private ArrayList _propretys;

        public ArrayList Propretys
        {
            get { return _propretys; }
            set { _propretys = value; }
        }

        private bool _colAdd = false;
        public bool ColAdd
        {
            get { return _colAdd; }
            set { _colAdd = value; }
        }

        #endregion
    }

因为笔者希望这些实体类在使用的同时就被记录下来,并被缓存下来,所以笔者有创建了ManageTabel类,用于缓存已被记录的实体类,以及初始化时获取特性等操作

 public static class ManageTabel
    {
        /// <summary>
        /// 用于缓存数据
        /// </summary>
        public static IDictionary<string, TabelInfo> _tabels=new Dictionary<string,TabelInfo>();

        public static bool IsHave(string key) {
            return _tabels.ContainsKey(key);
        }

        /// <summary>
        /// 初始化数据
        /// </summary>
        public static void Intital() {
            foreach (string key in _tabels.Keys)
            {
                TabelInfo ti = _tabels[key];
                if (ti.Propretys == null)
                {
                    //获取当前类中的公开属性
                    PropertyInfo[] pinfo = ti.TabelType.GetProperties();

                    foreach (PropertyInfo item in pinfo)
                    {
                        object[] attributes = item.GetCustomAttributes(typeof(BindFiledAttribute),false);
                        for (int i = 0; i < attributes.Length; i++)
                        {
                            //获取对应属性值
                            FileInfo fi = new FileInfo();
                            BindFiledAttribute ba = attributes[i] as BindFiledAttribute;
                            if(ba!=null)
                            {
                                fi.StrName = ba.StrName;
                                fi.Type = ba.Type;
                                fi.ReadFormat = ba.ReadFormat;
                                fi.WriteFormat = ba.WriteFormat;
                                fi.Index = i;
                                fi.IsIdentity = ba.IsIdentity;
                                fi.IsKey = ba.IsKey;
                            }
                            if (ti.Propretys == null)
                                ti.Propretys = new System.Collections.ArrayList();
                            ti.Propretys.Add(fi);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 重置
        /// </summary>
        public static void Result() {
            _tabels.Clear();
        }

        /// <summary>
        /// 添加数据到集合
        /// </summary>
        /// <param name="key">唯一标识列</param>
        /// <param name="ti">对象数据</param>
        /// <returns></returns>
        public static bool AddObject(string key, TabelInfo ti) {
            if (IsHave(key))
            {
                throw new Exception("当前数据已存在");
            }

            _tabels.Add(key,ti);
            return true;
        }

        /// <summary>
        /// 修改数据集
        /// </summary>
        /// <param name="key"></param>
        /// <param name="ti"></param>
        /// <returns></returns>
        public static bool EditeObject(string key, TabelInfo ti) {
            if (IsHave(key))
            {
                _tabels[key] = ti;
                return true;
            }
            throw new Exception("没有找到您想要替换的数据集");
        }

        /// <summary>
        /// 删除数据集
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool RemoveObject(string key) {
            if (IsHave(key))
            {
                _tabels.Remove(key);
                return true;
            }
            throw new Exception("没有找到您想要删除的数据集"); 
        }
    }
View Code

_tabels用于缓存数据使用,这里的方法和属性都是静态的,就是方便用户随时使用

好了,我们现在回到之前的TabelInfo类,这个类中,我们需要添加一个带参构造

 public TabelInfo(string name,Type t,bool colAdd) {
            _tabelName = name;
            _type = t;
            _colAdd = colAdd;
            if (!ManageTabel.IsHave(name))
            {
                ManageTabel.AddObject(name, this);
                ManageTabel.Intital();
            }
        }
View Code

这里主要是让他起到自动缓存和读取的作用,不至于我们忘记缓存等操作而增加操作

好,现在我们的第一步工作算是完成了,我们进入第二步工作,数据库的连接和数据库操作等

这里我们可以重新创建类库DBUitily.也可以继续在该类库下添加类,笔者比较喜欢分开写所以创建了类库

类库中我们创建类DBSqlServer类,该类主要针对sqlserver而编写的.因为笔者对其他数据库并不是很了解,这里就没有过多的去写了,读者可以自行改写.

这里先写关于数据库的连接字符串,笔者习惯从配置文件中读取该字符串,这里依然从配置文件中读取

private static string CONNECTION = ConfigurationManager.AppSettings["connection"].ToString();

现在编写关于数据库连接操作的一些基本操作

  #region 数据库执行
        /// <summary>
        /// 执行新增,删除,修改等语句
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static int ExecuteSql(string txt, CommandType cmdType, params SqlParameter[] paras)
        {
            int count = 0;
            using (SqlConnection conn = new SqlConnection(CONNECTION))
            {
                lock (conn)
                {
                    try
                    {
                        SqlCommand cmd = new SqlCommand();
                        CommondPar(conn, cmd, txt, cmdType, null, paras);
                        count = cmd.ExecuteNonQuery();
                    }
                    catch (Exception)
                    {
                        count = -1;
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open)
                        {
                            conn.Close();
                            conn.Dispose();
                        }
                    }
                }
                return count;
            }
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="txt"></param>
        /// <param name="cmdType"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static DataSet ExecuteDataRead(string txt, CommandType cmdType, params SqlParameter[] paras)
        {
            DataSet ds = new DataSet();
            using (SqlConnection conn = new SqlConnection(CONNECTION))
            {
                lock (conn)
                {
                    try
                    {
                        SqlCommand cmd = new SqlCommand();
                        CommondPar(conn, cmd, txt, cmdType, null, paras);
                        using (SqlDataAdapter da = new SqlDataAdapter(txt, conn))
                        {
                            da.SelectCommand = cmd;
                            da.Fill(ds);
                        }
                    }
                    catch (Exception)
                    {
                        ds = null;
                    }
                    finally
                    {

                        if (conn.State == ConnectionState.Open)
                        {
                            conn.Close();
                            conn.Dispose();
                        }
                    }
                }
                return ds;
            }
        }

        /// <summary>
        /// 公用方法
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="cmd">SqlCommand</param>
        /// <param name="text">sql语句或者存储过程名称</param>
        /// <param name="cmdType"></param>
        /// <param name="trans"></param>
        /// <param name="paras"></param>
        private static void CommondPar(SqlConnection conn, SqlCommand cmd, string text, CommandType cmdType, SqlTransaction trans, params SqlParameter[] paras)
        {
            if (conn == null || cmd == null)
                throw new Exception("缺少必要参数S去了Connection或者SqlCommand");
            else
            {
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
                cmd.CommandText = text;
                cmd.CommandType = cmdType;
                cmd.Connection = conn;
                if (trans != null)
                    cmd.Transaction = trans;
                if (paras != null)
                    cmd.Parameters.AddRange(paras);
            }
        }
        #endregion
View Code

如此,我们便可以写创建表和列的字符串了

    /// <summary>
        /// 创建表
        /// </summary>
        /// <param name="ti">数据源</param>
        /// <returns></returns>
        private  
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#list常用的几个操作改变list中某个元素的值替换某一段数据发布时间:2022-07-14
下一篇:
C#winformQrcoder二维码发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap