利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论:0 | 浏览:45 |

该类在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 { getset; }

        [Display(Name = "Meta描述")]

        public string Description { getset; }

}

//

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

Tags: Model MVC 泛型

?? 上一篇下一篇 ??

相关文章:

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送

利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

asp.net MVC通用分页组件 使用方便 通用性强

.NET C#生成随机颜色,可以控制亮度,生成暗色或者亮色 基于YUV模式判断颜色明亮度

微软官方SqlHelper类以及辅助访问类 简化使用方法

DataTable和DataRow利用反射直接转换为Model对象的扩展方法类

原文地址:https://www.cnblogs.com/cjm123/p/8620114.html

时间: 2024-10-22 03:29:32

利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理的相关文章

winform中利用反射实现泛型数据访问对象基类

考虑到软件使用在客户端,同时想简化代码的实现,就写了一个泛型的数据访问对象基类,并不是特别健全,按道理应该参数化的方式实现insert和update,暂未使用参数化,抽时间改进. /// <summary> /// DAO基类 实体名必须要与数据表字段名一致 /// </summary> /// <typeparam name="T"></typeparam> public class BaseDao<T> where T :

DataTable转任意类型对象List数组-----工具通用类(利用反射和泛型)

public class ConvertHelper<T> where T : new() { /// <summary> /// 利用反射和泛型 /// </summary> /// <param name="dt"></param> /// <returns></returns> public static List<T> ConvertToList(DataTable dt) { //

NPOI操作excel——利用反射机制,NPOI读取excel数据准确映射到数据库字段

> 其实需求很明确,就是一大堆不一样的excel,每张excel对应数据库的一张表,我们需要提供用户上传excel,我们解析数据入库的功能实现. 那么,这就涉及到一个问题:我们可以读出excel的表头,但是怎么知道每个表头具体对应数据库里面的字段呢? 博主经过一段时间的思考与构思,想到一法:现在的情况是我们有excel表A,对应数据库表B,但是A与B具体属性字段的映射关系我们不知.那我们是不是可以有一个A到B的映射文件C呢? 我想,说到这,大家就很明了了... 第一步:为每张excel创建一个与

利用反射,泛型,静态方法快速获取表单值到Model

在项目中经常需要处理表单,给model赋值,很烦人的一些重复代码.如下边的代码: News news = new News(); news.Id = int.Parse(Request.Form["Id"]); news.Category = int.Parse(Request.Form["Category"]); news.Title = Request.Form["Title"]; news.CreateTime = DateTime.Par

ObjC 利用反射和KVC实现嵌套对象序列化成JSON数据

原理: 0.创建一个新的可变字典:NSMutableDictionary 1.采用class_copyPropertyList函数遍历对象的属性 2.property_getName获取属性名,valueForKey获取属性内容. 3.判断该属性内容的Class: (1)假如为基础类型(NSString,NSNumber,NSNull),则直接返回,跳转到4操作. (2)假如为数组类型,先创建新的可变数组,再遍历旧数组中的内容,判断内容类型,重复3进行递归操作,直到找到基础类型.  通过setO

java利用反射将pojo转为json对象

最近做以太坊钱包项目需要与前台进行json交互,写一个工具类,经普通javaBean转为json对象 1 package util; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Method; 5 import java.util.List; 6 7 import org.web3j.protocol.core.methods.response.Transaction; 8 9 import com.alibaba

利用反射获取泛型

package com.duchong.aar.reflect.T; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class DemoT { public void test01(Map<String,Integer> m

利用vs将json格式直接转换成Model实体类

例如如下格式json: { "resultcode": "200", "reason": "查询成功", "result": { "area": "河南省郑州市", "location": "电信" }, "error_code": 0 } 第一步:复制上面的json内容 第二部:看图!直接就会在你的类文件中

hibernate sql查询后对象转换成实体类

在多表查询的时候使用hibernate的sql查询的时候,一般返回的是object[]数组,或者可以使用 session.createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);     session. session.createSQLQuery(sql).addEntity(entity.class); /**     * 分页查询sql,sql语句不包含起始记录数和查询记录数     * @pa