利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理
该类在MVC中可以方便管理配置信息,可以直接把Model储存进数据库或者从数据库去除数据转为Model.
1 何为配置项目?
比如网站的名称,页脚信息,meta中的KeyWord信息等,如果不想硬编码到网页里,就需要使用配置文件进行储存,通常都是储存到数据库中.使用的时候读取出来,也方便修改.
2 MVC中对于数据的编辑一般是Model建模,然后View调用强类型,使用诸如@Html.TextBoxFor(m=>m.Name)之类的方式,取值时可以直接取到Model,不用再根据Request.From来一个一个的去赋值.
3 MVC的特性提供了强大的数据自检能力,如果Model中属性为Int类型,那么输入的时候如果不是数字则会直接提示类型错误.该特性支持正则表达式,可以说不用写一句js代码就可以完成数据的服务器端和客户端双重验证,十分强大.
4 本类只有两个方法,一个Load 一个Save,顾名思义,一个读取一个储存.参数都采用了泛型.你可以创建一个ConfigWebSIteModel基本设置类,
然后再创建一个ConfigSeo类,来分别管理不同的配置项目,可以一并储存到一个数据表中.
| 
 1 
2 
 | 
        T Load<T>();        void Save<T>(T t); | 
不用的类中的属性不可以重复,否则会覆盖,比如ConfigWebSiteModel中有个ConfigWebSiteModel.Name 那么 ConfigSeo中就不能在出现Name属性,否则会覆盖掉,出错.
核心代码:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
 | 
    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Data;using System.Text;using ChengChenXu.Blog.Models;using System.Reflection;using System.Data.SqlClient;namespace ChengChenXu.Blog.DAL.SqlServer{    public class ConfigModelDAL:IConfigModelDAL    {        private readonly string tableName = "blog_Config";//表名        private readonly string columnKey = "c_Key";//key列名        private readonly string columnValue = "c_Value";//Value列名        private readonly string columnType = "c_Type";//Type列名                /// <summary>        /// 加载        /// </summary>        /// <typeparam name="T"></typeparam>        /// <returns></returns>        public T Load<T>()        {            //通过sqlhelper获取datatable            string sql = "select * from " + tableName;            DataTable dt = SqlHelper.ExecuteDataTable(sql);            //不存在记录            if (dt.Rows.Count == 0) return default(T);            //表行转换成列 ,临时表            DataTable temp = new DataTable();            foreach (DataRow dr in dt.Rows)            {                //添加一列,设置列的数据类型                DataColumn dc = new DataColumn();                dc.ColumnName = dr[columnKey].ToString();                //根据字符串设置数据类型                dc.DataType = System.Type.GetType(dr[columnType].ToString());                temp.Columns.Add(dc);                //如果时第一列,添加一行                int index = temp.Columns.Count - 1;                if (temp.Rows.Count == 0) temp.Rows.Add();                //如果不是第一例,则行必定已经存在,直接赋值                temp.Rows[0][index] = dr[columnValue];            }            if (temp.Columns.Count == 0) return default(T);            //把临时表转换成Model并返回            return temp.Rows[0].ToModel<T>();        }        /// <summary>        /// 保存        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="t"></param>        public void Save<T>(T t)        {            //利用反射获取对象所有属性            string attributeName = String.Empty;            PropertyInfo[] propertys = t.GetType().GetProperties();            //获取数据库配置表放到内存中,对比数据是否已经存在            DataTable dt = new DataTable();            if (propertys.Length > 0)            {                dt = SqlHelper.ExecuteDataTable("select * from "+tableName+"");                //给表设置主键,方便查找.                dt.PrimaryKey=new[] {(dt.Columns[columnKey])};            }            //依次保存对象属性到数据库            foreach (PropertyInfo pi in propertys)            {                //获取属性值                var a = pi.GetValue(t, null);                //值为NULL跳出,不保存,进入下个循环                if (a == null)                {                    SqlHelper.ExecuteNonQuery("delete from "+tableName+" where "+columnKey+" =‘"+pi.Name+"‘ ");                    continue;                }                //准备sql参数                SqlParameter[] parameters = SqlHelper.CreatParameters(                    new string[] { "Key", "Value" ,"Type"},                    new object[] { pi.Name, a, a.GetType().ToString() }                    );                //查找属性是否已经存在于数据库中                if(dt.Rows.Contains(pi.Name))                {                    //存在 更新属性                    SqlHelper.ExecuteNonQuery(                        "update " + tableName + " set " + columnValue + " = @Value , " + columnType + " = @Type where " + columnKey + " = @Key",                        parameters                        );                }                else                {                    //不存在 插入属性                    SqlHelper.ExecuteNonQuery(                        "insert into " + tableName + " (" + columnKey + "," + columnValue + "," + columnType + ") values (@key,@value,@type) ",                        parameters                        );                }            }        }    }} | 
该类用到了两个外部类,一个是SqlHelper 就是普通的数据库辅助类,只用到了根据Sql语句和参数进行查询,更新,插入的功能,可以替换为自己的Helper类或者直接在此类中完成数据库操作
另外一个是把DataRow转换为Model对象的类,这个类是一个扩展方法,引用之后就可以直接对DataRows实例进行ToModel操作了.
| 
 1 
 | 
return temp.Rows[0].ToModel<T>(); | 
Sqlhelper类不再贴出,可以自己查找.扩展方法见本文:http://www.chengchenxu.com/Article/10/
本博客源码中也使用了此类,可以关注后期整理好源码后会开源,可以参考用法.
使用方法很简单:
1 这四个属性对应数据库中的表名以及列名,可以自定义,例如下图这样.
| 
 1 
2 
3 
4 
 | 
        private readonly string tableName = "blog_Config";//表名        private readonly string columnKey = "c_Key";//key列名        private readonly string columnValue = "c_Value";//Value列名        private readonly string columnType = "c_Type";//Type列名 | 

key要设置为主键,类型都为varchar,长度视情况而定.
2 数据库链接字符串都是sqlHelper类中定义,SqlHelper类参考文章:http://www.chengchenxu.com/Article/11/sqlhelper
3 创建一个Model
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
 | 
public class ConfigSeoModel{        [Display(Name = "Meta关键字")]        public string KeyWord { get; set; }        [Display(Name = "Meta描述")]        public string Description { get; set; }}//ConfigModelDAL dal=new ConfigModelDAL();//new 一个ModelConfigSeoModel model=new ConfigSeoModel();model.KeyWord="关键字";model.Description = "描述"//完成保存dal.Save<ConfigSeoModel>(model);  //读取ConfigSeoModel model = dal.Load<ConfigModel>(); | 
本文为博主原创,转载请保留出处:
http://www.chengchenxu.com/Article/24/fanxing