博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入医生orm之insert细节
阅读量:6139 次
发布时间:2019-06-21

本文共 6965 字,大约阅读时间需要 23 分钟。

这是第一次看一个组件的细节和内幕,好在医生的代码注释很多,堪称典范

首先是看看生成的实体类

 

因为医生宣称自己的orm没有使用反射,对此深感好奇,就看看是怎么插入数据和映射的

生成的实体类代码如下

using System;using PWMIS.Common;using PWMIS.DataMap.Entity;namespace SuperMarket {  [Serializable()]  public partial class userinfo : EntityBase  {    public userinfo()    {            TableName = "userinfo";            EntityMap=EntityMapType.Table;            //IdentityName = "标识字段名";    IdentityName="id";            //PrimaryKeys.Add("主键字段名");    PrimaryKeys.Add("id");                }      protected override void SetFieldNames()      {           PropertyNames = new string[] { "id","username","userpassword","userbrief","userimg" };      }      ///       ///       ///       public System.Int32 id      {          get{
return getProperty
("id");} set{setProperty("id",value );} } ///
/// /// public System.String username { get{
return getProperty
("username");} set{setProperty("username",value ,50);} } ///
/// /// public System.String userpassword { get{
return getProperty
("userpassword");} set{setProperty("userpassword",value ,50);} } ///
/// /// public System.String userbrief { get{
return getProperty
("userbrief");} set{setProperty("userbrief",value ,1073741823);} } ///
/// /// public System.String userimg { get{
return getProperty
("userimg");} set{setProperty("userimg",value ,50);} } }}
 
[Serializable()]
首先这个实体类是可以序列化的,为以后的缓存做好了准备,不过这个效率不太高,实现可序列化接口就更好了
userinfo : EntityBase
实体类继承字同一个实体对象,基类应该是对象转换相关的

TableName = "userinfo";

这里指定了实体对应的表的名称,应该是生成sql预计时候用的,也为以后的分库分表横向拆分做好了准备

EntityMap=EntityMapType.Table;

 

protected override void SetFieldNames()

     {
          PropertyNames = new string[] { "id","username","userpassword","userbrief","userimg" };
     }

这里保存了一个表所有的字段的名称

 

     /// <summary>

     ///
     /// </summary>
     public System.Int32 id
     {
         get{return getProperty<System.Int32>("id");}
         set{setProperty("id",value );}
     }

这里是一个字段的属性,对这个属性进行读写时,并不是直接读写,而是调用基类的方法,进行存储

实体类就这么多

再调式看看

调试上次插入的代码

SuperMarket.userinfo objuserinfo = new SuperMarket.userinfo();            EntityQuery
query = new EntityQuery
(objuserinfo,true); objuserinfo.username = "互联网fans"; objuserinfo.userpassword = "1234567"; objuserinfo.userimg = "http://tp2.sinaimg.cn/1271114553/180/5614484664/1"; objuserinfo.userbrief = @"博客园菜鸟级博主,七脸阁主题APP开发者,专注于WebApp的开发和研究,提倡通过命题作文寻找创新的灵感和创意的点子。新浪应用搜索最新作品:表情帝。"; //query.Save(); // Response.Write(objuserinfo.id); int id= query.Insert(objuserinfo); Response.Write(id);

先跟中一下赋值,医生的orm赋值有很多猫腻在里面,得看看

objuserinfo.username = "互联网fans";

跟进去后

进入赋值环节

赋值环节先根据表名称和字段名称生成了个key,然后存储了字段的长度,并比较了值的长度是否溢出,防止插入数据库时出错

检查完成后开始赋值

这里不清楚是所有的属性默认都是null,还是因为我的表设计的默认值允许为null,下次在检验一下

赋值时对PropertyNames属性列表进行遍历,找到赋值的属性就赋值,并在changedlist[i] 标记这个值已经变化了,为插入数据库时只插入赋值的字段做好了准备

另外这里还注册了一个事件,虽然没弄明白注册这个时间是干嘛的有什么用,有没有性能风险,例如,web并发时候注册事件有没有影响,主要是不知道这个是干嘛的

赋值到这里就完了,医生之所以没用使用映射,就是记录了表一共有那些字段,给那些字段赋值了,然后就可以插入了

插入是个方法,医生没有放到实体类里面去而是新建了查询类

EntityQuery<SuperMarket.userinfo> query = new EntityQuery<SuperMarket.userinfo>(objuserinfo,true);

public EntityQuery(T entity,bool newEntity)

{
     isNew = newEntity;
     init(entity);
}

private void init(T entity)

{
    entity.PropertyGetting += new EventHandler<PropertyGettingEventArgs>(entity_PropertyGetting);
    entity.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(entity_PropertyChanged);
    currEntity = entity;
}

创建这个查询时也注册了不少事件,并指定了这个查询是那个实体类的查询,不清楚web应用程序频繁的注册事件对性能影响几何,哎

跟入inser方法

在insert 方法中先判断了一下实体中字段的数量,然后指定了默认的数据库连接字符串

在接下来

private static int InsertInner(T entity, List
objFields, CommonDB DB) { if (objFields == null || objFields.Count == 0) return 0; IDataParameter[] paras = new IDataParameter[objFields.Count]; //CommonDB DB = MyDB.GetDBHelper(); string sql = "INSERT INTO [" + entity.TableName+"]"; string fields = ""; string values = ""; int index = 0; foreach (string field in objFields) { if (entity.IdentityName != field) { fields += ",[" + field+"]"; string paraName = DB.GetParameterChar + "P" + index.ToString(); values += "," + paraName; paras[index] = DB.GetParameter(paraName, entity.PropertyList(field)); //为字符串类型的参数指定长度 edit at 2012.4.23 if( paras[index].Value!=null && paras[index].Value.GetType()==typeof(string)) { ((IDbDataParameter)paras[index]).Size = entity.GetStringFieldSize(field); } index++; } } sql = sql + "(" + fields.TrimStart(',') + ") VALUES (" + values.TrimStart(',') + ")"; int count = 0; if (entity.IdentityName != "") { //有自增字段 object id = entity.PropertyList(entity.IdentityName); count = DB.ExecuteInsertQuery(sql, CommandType.Text, paras, ref id); entity.setProperty(entity.IdentityName, Convert.ToInt32(id)); } else { count = DB.ExecuteNonQuery(sql, CommandType.Text, paras); } if (count > 0) entity.ResetChanges(); return count; }

 

if (objFields == null || objFields.Count == 0)

    return 0;

IDataParameter[] paras = new IDataParameter[objFields.Count];

判断有没有字段,然后根据字段的数量创建参数列表

string sql = "INSERT INTO [" + entity.TableName+"]";

           string fields = "";
           string values = "";
           int index = 0;

           foreach (string field in objFields)

           {
               if (entity.IdentityName != field)
               {
                   fields += ",[" + field+"]";
                   string paraName = DB.GetParameterChar + "P" + index.ToString();
                   values += "," + paraName;
                   paras[index] = DB.GetParameter(paraName, entity.PropertyList(field));
                   //为字符串类型的参数指定长度 edit at 2012.4.23
                   if( paras[index].Value!=null && paras[index].Value.GetType()==typeof(string))
                   {
                       ((IDbDataParameter)paras[index]).Size = entity.GetStringFieldSize(field);
                   }
                   index++;
               }
           }
           sql = sql + "(" + fields.TrimStart(',') + ") VALUES (" + values.TrimStart(',') + ")";

遍历字段 拼写sql并给sql参数赋值

if (entity.IdentityName != "")

{
    //有自增字段
    object id = entity.PropertyList(entity.IdentityName);
    count = DB.ExecuteInsertQuery(sql, CommandType.Text, paras, ref id);
    entity.setProperty(entity.IdentityName, Convert.ToInt32(id));
}
else
{
    count = DB.ExecuteNonQuery(sql, CommandType.Text, paras);
}

在执行 sql语句时候,看有没有自增id,如果有自增id,执行时返回自增的id,没有的话就返回影响的行数

感觉这里IdentityName 不太准确,自增id,主键,等等应该详细描述

插入的就这么多

剩下的就是调用sql帮助类了

另外发现,orm默认没有实现读写分离,这点很不好。。。。。。。。。。。。。。。。。。

                    

 

转载地址:http://bjkya.baihongyu.com/

你可能感兴趣的文章
centos64i386下apache 403没有权限访问。
查看>>
vb sendmessage 详解1
查看>>
jquery用法大全
查看>>
PC-BSD 9.2 发布,基于 FreeBSD 9.2
查看>>
网卡驱动程序之框架(一)
查看>>
css斜线
查看>>
Windows phone 8 学习笔记(3) 通信
查看>>
重新想象 Windows 8 Store Apps (18) - 绘图: Shape, Path, Stroke, Brush
查看>>
Revit API找到风管穿过的墙(当前文档和链接文档)
查看>>
Scroll Depth – 衡量页面滚动的 Google 分析插件
查看>>
Windows 8.1 应用再出发 - 视图状态的更新
查看>>
自己制作交叉编译工具链
查看>>
Qt Style Sheet实践(四):行文本编辑框QLineEdit及自动补全
查看>>
[物理学与PDEs]第3章习题1 只有一个非零分量的磁场
查看>>
深入浅出NodeJS——数据通信,NET模块运行机制
查看>>
onInterceptTouchEvent和onTouchEvent调用时序
查看>>
android防止内存溢出浅析
查看>>
4.3.3版本之引擎bug
查看>>
SQL Server表分区详解
查看>>
使用FMDB最新v2.3版本教程
查看>>