学习ORM,从最简单的例子开始...之一

    技术2022-05-11  55

    [前言]         之所以贴在首页区,不是因为代码(来自国外一位同行的作品)如何精简,而是因为我希望通过这次由简到全的改造历程,能够让自己对ORM的理解和掌握有个新的提高。         此前,我同样把自己的一个很小很简单,甚至很“初学者”的“心得”贴到首页区,结果招来某些园客的抨击和鄙视。是的,那个问题是很“初学”,但我觉得,有的时候,忘记脑子里面原有的东西,以一个初学者的心态来看问题,一定会有一番新的收获。学习知识不是一件可耻的事情,没有人能够面面俱到。         希望能给O/RM的初学者带来一点帮助。 [改造计划]         1、不用每次遍历所有的映射文件,只需查找当前对象所映射的文件。         2、分层,做到与PetShop架构结合。         3、用Attribute实现。目前Demo例子是用xml做映射文件的。 点击这里下载最原始的Demo[2007.1.25版] 1、Demo详述:      首先看下类视图及代码说明:

    另外在APP_Code下 有:ORMappings/Employee.xml;ORMappings/Person.xml                                                 看看代码是如何调用的吧:

    for  ( int  i  =   0 ; i  <   1000 ; i ++ ) {   Employee emp = new Employee(i + 1, i, "firstName" + i, "lastName" + i);   ObjectStore<Employee>.Insert("myDB", emp);} 代码说明:很简单,实例化一个Employee对象,同样可以实例化一个Person对象并如下调用 Person person  =   new  Person( " person_f " " person_l " );ObjectStore < Person > .Insert( " myDB " , person); Insert方法 public   static   string  Insert( string  cnHint, T obj) {   return Execute(obj, cnHint, "Insert");}

     

    好了以下就让我们看看Execute(T obj, string cnHint, string cmdName)方法都做了什么吧:

    public   static   string  Execute(T obj,  string  cnHint,  string  cmdName)         {            DateTime start = DateTime.Now;            MappingInfo map = MappingStore.TheInstance.GetMappingInfo(obj.ToString());//            CommandInfo cmdInfo = map.Commands[cmdName];//获取操作命令            using (DbConnection cn = DbConnectionStore.TheInstance.GetConnection(cnHint))//打开连接            {                DbCommand cmd = DbCommandStore.TheInstance.GetCommand(cnHint, cmdInfo.CommandText);//建立一个Command对象                cmd.Connection = cn;                _setParamValues(obj, cmd, cmdInfo);                cmd.ExecuteNonQuery();                _getParamValues(obj, cmd, cmdInfo);//执行            }            TimeSpan duration = DateTime.Now - start;            return duration.ToString();        }

    以上代码和一般的ADO.NET数据库操作类似。下面再来看看映射文件的结构,以Emplyee为例:<?xml version="1.0" encoding="utf-8" ?><object.mappings> <object.mapping for="Employee" namespace="ClassLibrary1">  <command type="Insert">   <text>    dbo.EMPLOYEE_INS_SP   </text>   <parameters>    <add objMember="_employeeId" dbMember="@EmployeeId"/>    <add objMember="_firstName" dbMember="@FirstName" />    <add objMember="_lastName" dbMember="@LastName" />    <add objMember="_age" dbMember="@Age" />   </parameters>  </command><!--省略了Select和Update的映射,代码可见Demo--> </object.mapping></object.mappings> 

    我们再看看MappingStore.cs这个文件中的类:

    其中有三个类(我觉得这里就不是很符合规范,一个文件包含了三个类,但至少阅读起来的确比较方便)

    ·MappingStore类:负责加载映射文件,这里的Demo是遍历所有映射文件,然后通过GetMappingInfo(string typeName)方法返回一个MappingInfo类对象。

    ·MappingInfo类:负责加载映射文件中的所有Command,保存在Dictionary<TKey, TValue>中,其中TKey是CommandTtype,比如“Insert”、“Select”、“Update”等,TValue就是一个CommandInfo类对象。

    ·CommangInfo类:负责加载映射文件中的Parameters参数,也是保存在一个Dictionary< TKey, TValue>中,其中TKey是映射文件中dbMember,这个dbMember必须和数据库的字段名一致;TValue是objMember,对应Employee和Person这两个实体类的参数名。 


    最新回复(0)