【实体类变形】—— 元数据(另类ORM) 描述字段的数据

 

     放假了,不知道有没有加班的,先祝大家国庆节快乐!

     上次说得有点乱,“行列转换”这个词可能误导了大家,那么把这个词扔掉吧。我们重新开始。假设我们有一个News表,我们要往里面添加数据,我们先只考虑保存数据的部分。

一、我们定义一个类。变形的“实体类”

 public class ColumnsInfoBase       
    {
        #region 字段的基本信息的描述
        /// <summary>
        /// 配置信息里面的字段的标识
        /// </summary>
        public int ColumnID = 0;

        /// <summary>
        /// 数据库里的字段名称
        /// </summary>
        public string ColSysName = "";

        /// <summary>
        /// 显示给客户看的名称
        /// </summary>
        public string ColName = "";

        /// <summary>
        /// 字段类型,int nvarchar 等
        /// </summary>
        public string ColType = "";

        /// <summary>
        /// 字段大小
        /// </summary>
        public Int32 ColSize = 0;

        /// <summary>
        /// 字段值
        /// </summary>
        public string ColValue;
   
        #endregion

    }

 

二、XML文件,表结构。新闻表里面有一个新闻名称的字段(Title),nvarchar(50)的;有一个新闻内容的字段等, 那么我们可以这样来设置这样一个XML文件,来对字段进行描述。

XML文件,说明字段
<?xml version="1.0" standalone="yes"?>
<Test>
  <News>
    <col ColumnID="101" ColSysName="NewsID" ColName="标识" ColType="int" ColSize="4"></col>
    <col ColumnID="102" ColSysName="Title" ColName="新闻标题" ColType="nvarchar" ColSize="50"></col>
    <col ColumnID="103" ColSysName="Content" ColName="内容" ColType="ntext" ColSize="16"></col>
    <col ColumnID="104" ColSysName="AddedDate" ColName="添加时间" ColType="datetime" ColSize="8"></col>
    <col ColumnID="105" ColSysName="Hits" ColName="人气" ColType="int" ColSize="4"></col>
  </News>
</Test>

 

三、加载。然后我们可以写一个这样的代码来加载“实体类”

Dictionary<int, ColumnsInfoForm> dic_BaseCols = new Dictionary<int, ColumnsInfoForm>();

            ColumnsInfoForm info;

            info = new ColumnsInfoForm();

            //属性值要从XML文件里面获取,这里为了简洁直接赋值了。
            info.ColumnID = 101;        //从XML文件里面获取
            info.ColSysName = "Title";       //从XML文件里面获取
            info.ColName = "新闻标题";       //从XML文件里面获取
            info.ColType = "nvarchar";       //从XML文件里面获取
            info.ColSize = "50";       //从XML文件里面获取

            dic_BaseCols.Add(info.ColumnID, info);

     四、动态得到SQL语句。现在我们要实现添加数据的功能,不对要叫做“持久化”了,我们可以这样来拼接SQL语句。

 

Code
//获取参数化的Insert into 语句
public string GetSQL_InsertIntoParameter(string TableName)
{
 ColumnsInfoBase bInfo;
 #region 拼接参数化SQL语句 insert into 
                                
                                str.Append("insert into  ");
                                str.Append(TableName);       //表名

                                //字段
                                str.Append(" ( ");
                                foreach (KeyValuePair<int, ColumnsInfoForm> info in dic_BaseCols)
                                {
                                    bInfo = (ColumnsInfoBase)info.Value;
                                    str.Append(bInfo.ColSysName);
                                    str.Append(",");
                                }
                                str.Remove(str.Length - 1, 1);  //去掉作后的 , 号
                                str.Append(" ) values (");

                                foreach (KeyValuePair<int, ColumnsInfoForm> info in dic_BaseCols)
                                {
                                    bInfo = (ColumnsInfoBase)info.Value;
                                    str.Append("@");
                                    str.Append(bInfo.ColSysName);
                                    str.Append(",");
                                }

                                str.Remove(str.Length - 1, 1);  //去掉作后的 , 号
                                str.Append(" ) ");
#endregion
return str.Tostring();
}

 

     我们还需要存储过程的参数

 

得到存储过程的参数
ColumnsInfoBase bInfo;

            System.Data.SqlClient.SqlParameter par;

            foreach (KeyValuePair<int, ColumnsInfoForm> info in dic_BaseCols)
            {
                bInfo = (ColumnsInfoBase)info.Value;

                par = new System.Data.SqlClient.SqlParameter();
                par.ParameterName = "@" + info.ColSysName;
                switch (info.ColType)
                {
                    case "int":
                        par.Size = 4;
                        par.SqlDbType = SqlDbType.Int;
                        break;
                    case "nvarchar":
                        par.Size = info.ColSize;
                        par.SqlDbType = SqlDbType.NVarChar ;
                        break;
                        //其他略
                }
            }

 

     这样我们就可以得到存储过程的参数了。

     有了参数化的SQL语句(insert into)还有存储过程的参数,那么下面就好办了。我们可以交给SQLHelp、DbHelp、自己写的Help或者直接写SqlCommand。总之怎么做都可以了。用我的数据访问函数库也可以。

     这个可以扩展一下,不仅是新闻表可以使用,其他的表也是可以使用的,只要设置不同的XML文件就可以了。
 

 

ORM与另类ORM的区别

     1、ORM是类和表的对应,一个类可以和一个表或者多个表对应,一个表也可以和一个类或者多个类对应。类的属性(表的字段)不能独立存在,也不能被拆分;

     而另类ORM是类和字段的对应。类的属性是对字段的描述信息,类——也就是字段——是可以随意组合的。就是说是可以以字段为最小单位进行灵活组合。这样就可以大大提高效率,延迟加载也就用不上了,比延迟加载更灵活和可控制!

     2、一般的实体类是把字段作为属性来处理的(为了少写代码,就需要使用反射),这样字段变化了就需要修改实体类,这就带来了很多的修改。     

     而另类实体类是把字段信息作为属性值来处理的,这样字段变化了只需要属性值就可以了,而属性值又是由XML文件里面提取的,所以只需要修改XML文件就可以了,不用修改实体类。不修改实体类,与之相关的很多地方都不用修改代码了。这样当字段变化,基本上只改一条配置信息就可以了。

     3、一般的实体类携带的信息有限,只有字段名和字段值,而要获取字段名还需要一个“潜规则”那就是要用字段名来命名属性名,然后再用反射的方式来获得,兜了一个大圈子。至于字段类型和字段大小就没有地方放了。

     而另类的实体类采用属性值的方式来存放各种信息,这样可以用增加属性的方式来存放更多的信息,比如ColumnsInfoBase  类里面的属性就可以分别存放字段名称、字段类型、字段大小和字段值。 这样想放什么类型的信息都可以。用的时候只需要提取属性值就可以了,不用反射。

 

另类ORM的优点:

     1、项目再大,添加数据(持久化)只需要这几个函数加上一个help就可以了,代码和文件都不会增加,只需要增加xml文件就可以了。

     2、数据层大大瘦身,变成了固定的几个函数 + Help 的形式,这样其他的项目也可以共用,大大节省了开发时间,这样才可以真正的不用思考如何持久化,把大部分的精力都放在业务逻辑的处理上!

     3、字段变化了也不用修改代码(不仅是数据层的,UI层也是不用修改的,如果业务逻辑简单,那么逻辑层也是不用修改的,只有在很复杂的业务逻辑的情况下,才有可能需要就改逻辑层,不过这个修改的原因不是因为字段变化了,而是业务逻辑变化了,还有要注意的是,即使是业务逻辑变了,其它层也是不需要修改的),只需要修改xml文件即可。这个是针对三层的最大的缺点来优化的!效果很好

     3、文件、代码减少了之后会带来很多的方便。比如编译时间,一、两秒就可以完成。备份文件的时间也大大减少。要写的代码少了,工作量自然也就减少了。不用代码生成器也可以很方便。

 

时间: 2024-07-31 05:00:56

【实体类变形】—— 元数据(另类ORM) 描述字段的数据的相关文章

link环境下实体类的继承,通过type字段映射给不同类型,codefirst可以做到么?

问题描述 link环境下实体类的继承,通过type字段映射给不同类型,codefirst可以做到么? link环境下实体类的继承,通过type字段映射给不同类型,codefirst可以做到么? 解决方案 http://www.cxyclub.cn/n/54711/

MyBatis学习教程(四)-如何快速解决字段名与实体类属性名不相同的冲突问题_java

在项目开发中,我们经常会遇到表中的字段名和表对应实体类的属性名称不一定都是完全相同的情况,下面小编给大家演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突问题,感兴趣的朋友一起学习吧. 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, or

C# 三层中的实体类有什么用呢?

问题描述 我想问问假设现在有实体类(Model.cs)privatestringUID=string.empty;privatestringUNAME=string.empty;publicstringID{get{returnUID;}set{UID=value;}}publicstringNAME{get{returnUNAME;}set{UNAME=value;}}然后到业务逻辑层(BLL)最后就数据链路层(DAL)当中实体类就是用来干什么的,能举个例子说明吗? 解决方案 解决方案二:这样

Web Api 返回实体类,接收时自动转成的Json问题

问题描述 实体类如下:服务端接口是返回这个实体类,接收的Json的字段全是_cr_sn_cr_guid全是我私有变量,我要的CR_SN等,我的公共变量如果我在服务端,手动用Json转成字符串,则完成没问题,字段都是公共变量怎么在不改动实体类的情况下,解决这个问题我现在的解决方案是,手动转成Json字符串,返回值改为string,(之前是实体类),这样的坏处就是,我接收到的数据,需要反转两次,才能得到真正的数据,但这并不是我想要能不能重写webApi的自动转Json的方法?或者有什么其他方案?求大

Mybatis实体类和表映射问题(推荐)_java

本文是小编给大家带来的mybatis中实体类和表映射问题的知识,学习本教程能够快速帮助我们解决字段名与实体类属性名不相同的冲突问题,需要的朋友一起看看吧! 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('a

hibernate注解实体类对应数据库字段,出了问题?请教

问题描述 hibernate注解实体类对应数据库字段,出了问题?请教 我在用注解写对应数据库的映射文件时候 搞了个单元测试 结果就报了异常 : org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commonDao': Autowiring of fields failed; nested exception is org.springframework.beans.fac

原生sql hibernate-用原生sql查询 为什么实体类中存在该字段,但为什么还是报错列名无效

问题描述 用原生sql查询 为什么实体类中存在该字段,但为什么还是报错列名无效 这是dao层 ds = HibernateDataSource.getHibernateDataSource(); session = ds.getSession(); String sql1="SELECT CHANNEL_ID FROM JC_CHANNEL WHERE PARENT_ID='"+ channelId + "'"; SQLQuery sqlQuery1 = sessi

“实体类”可不可以动态添加“字段”和“属性”

问题描述 "实体类"可不可以动态添加"字段"和"属性"???比如一个实体类,如下:publicclassEnergyTargetModel{publicstringEnergyYear{get;set;}publicstringEnergySum{get;set;}publicstringEnergyUnitArea{get;set;}publicstringEnergyEveryOne{get;set;}}功能:现在要根据参数"Sum

实体类的变形【1】—— 餐盘原理

      在亚历山大同学的post里面我说可以让实体类和表不必一一对应,但是并没有详细说明如何来做,也有人想问我是怎么做的,那么我就说一下.先说一个简单一点的,那就是在网页里面显示列表数据的情况,其他的下次再说.我们先来看一个生活中的情况,然后再说程序里面如何来做.   餐盘原理--模糊对应        餐盘,大家去食堂吃饭的时候,是不是会用一个长方形的餐盘来盛饭和菜呢?长方形的餐盘里有一个大一点的长方形的阁子,可以用来盛饭,当然也可以放馒头.花卷.面条等:有两.到四个个小一点的阁子,可以盛