利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理
利用反射和泛型把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 一个Model ConfigSeoModel model= new ConfigSeoModel(); model.KeyWord= "关键字" ; model.Description = "描述" //完成保存 dal.Save<ConfigSeoModel>(model); //读取 ConfigSeoModel model = dal.Load<ConfigModel>(); |
本文为博主原创,转载请保留出处:
http://www.chengchenxu.com/Article/24/fanxing
相关文章:
利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理的更多相关文章
- winform中利用反射实现泛型数据访问对象基类(1)
考虑到软件使用在客户端,同时想简化代码的实现,就写了一个泛型的数据访问对象基类,并不是特别健全,按道理应该参数化的方式实现insert和update,暂未使用参数化,抽时间改进. /// <su ...
- winform中利用反射实现泛型数据访问对象基类(3)
继续完善了几点代码 满足没有主键的情况下使用 并且完善实体字段反射设置value时的类型转换 /// <summary> /// DAO基类 实体名必须要与数据表字段名一致 /// < ...
- winform中利用反射实现泛型数据访问对象基类(2)
在1的基础上做了一点改进 参数化处理 看上去更简洁 无主键情况下 update 方法需要改进 insert delete没有问题 /// <summary> /// DAO基类 ...
- C#利用反射和泛型给不同对象赋值
/// <summary> /// 适用于初始化新实体 /// </summary> static public T RotationMapping<T, S>(S ...
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
- DataTable转任意类型对象List数组-----工具通用类(利用反射和泛型)
public class ConvertHelper<T> where T : new() { /// <summary> /// 利用反射和泛型 /// </summa ...
- 项目一:第五天 1、区域数据(pinyin4j-简码,城市编码) 2、Web层代码重构(model对象,分页代码提取) 3、区域分页查询 3、分区添加功能 4、定区管理管理-添加,分页
Service: /** * @Description: 1.保存定区 2.让分区关联定区 * 对象三种状态 1.持久态(被session管理对象-一级缓存中有对象) 2.托管态(有OID标识,数据 ...
- 利用反射,泛型,静态方法快速获取表单值到Model
在项目中经常需要处理表单,给model赋值,很烦人的一些重复代码.如下边的代码: News news = new News(); news.Id = int.Parse(Request.Form[&q ...
- 利用反射的特性将DataReader对象转化为List集合
问题:将SqlDataReader对象转换为List<T>集合 思路: 1,利用反射的特性得到对应实体Model的公共属性 Type type = typeof(T); PropertyI ...
随机推荐
- [python 函数学习篇] 关键字参数
函数可以通过 关键字参数 的形式来调用,形如 keyword = value .例如,以下的函数: def parrot(voltage, state='a stiff', action='voom' ...
- EOJ Monthly 2018.4
A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...
- [错误处理]python大小写敏感,关键字不要写错
今天调试程序,发现了一个极为隐蔽的bug. True False关键字大小写写错了,然后半天没找出问题所在.
- JS进行人民币大小写转换
//数字金额大写转换(可以处理整数,小数,负数) function upDigit() { digit=$("#digit").html(); n=digit.replace(/\ ...
- hdu3667
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 九度oj 题目1358:陈博的平均主义
题目描述: 在JOBDU团队里,陈博是最讲平均主义的人了,但并不是像梁山好汉那样能够做到有钱同花,有肉同吃,毕竟,他还是被家里的领导管着的……陈博的平均主义,就只能体现在他对数字的喜好了.陈博特别喜欢 ...
- 【转】深入JVM系列(一)之内存模型与内存分配
http://lovnet.iteye.com/blog/1825324 一.JVM内存区域划分 大多数 JVM 将内存区域划分为 Method Area(Non-Heap),Heap,Progr ...
- linux磁盘问题排查
一.ls $>>ls /data* //查看有无input/output error报错 二.demsg $>>demsg|grep sd 问题盘结果: 三.iostat使用 ...
- 【Luogu】P3745期末考试(三分)
题目链接 我是怎么把“期末考试”在本地写成“假期计划”的 qwq???? 本题把学生和卷子都排个序,按出成绩最晚时间三分. 三分之后可以O(n)的时间统计答案,因为修改卷子出成绩的时间可以贪心计划. ...
- 【反省】qqxt第一场考试
我太蒟了 qwq 这是第一条 2:考试别水群,别乱fake,特别是要避免出现不顾考试时间每件事fake十分钟的情况 3:少想多写,虽然说写数据结构之前一定要先想好但是别墨迹. 4:保持对考试的敬畏,别 ...