利用反射和泛型把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