• 不要EntityFramework,不要NHibernate,打造自己的ORM(二)


    我的ORM,暂时命名为LinFramwork吧,有如下特点:

    一 不仅支持若干主流数据库SQL Server,Oracle等,基于我前面随笔里阐述的通用数据访问组建原理,只要提供相关数据库ADO.NET Provider,并实现SQL解析的接口,还可以支持新的数据库类型。同时,对于调用者完全"透明",即开发人员只需定义数据库连接字符串即可,无须象其他ORM那样,还要在配置文件里加上数据库类型的属性。对于Oracle,我直接集成了Oracle的ODP.NET的相关dll,使其免客户端安装。简而言之,假如把数据库从SQL Server切换到Oracle,把连接信息改改即可。
    客户端配置文件

     <connectionStrings>
            <add name="MSSQL"  connectionString="Data Source=localhost\sqlexpress;
                 Initial Catalog=Northwind;Integrated Security=True"/>
            <add name="Oracle" connectionString="Data Source=(DESCRIPTION =(ADDRESS_LIST=
                 (ADDRESS=(PROTOCOL=TCP)(HOST=192.168.116.128)(PORT = 1521)))(CONNECT_DATA =
                 (SID = xe)(SERVER = DEDICATED)));User ID=sa;password=sa" />      
        </connectionStrings>
    

      客户端初始化实体对象上下文

                EntityContext sqlContext = new EntityContext(ConfigurationManager.ConnectionStrings["MSSQL"].ConnectionString);
                EntityContext oraleContext = new EntityContext(ConfigurationManager.ConnectionStrings["Oracle"].ConnectionString);
    


    二 类似EF的Codefirst,只需简单的定义一个实体。

     public class Categories
        {
            public int CategoryID { get; set; }
            public string CategoryName { get; set; }
            public string Description { get; set; }
    
        }
    

     注意看实体的定义与一般ORM的区别,我看过很多人自己开发的ORM,均觉得实体定义太罗嗦了,或者NH那样搞一大堆xml定义实体,或者像EF那样必须继承一个实体基类,或者在实体的属性上加上一堆特性定义,诸如对应的数据库表名称,字段名称,是否主键,是否自增,字段类型等等(很多orm同时具备以上几点),而我这里的设计,就这么简单,可以什么特性都不加,也不用继承什么实体基类,更不用再搞一堆xml。 

    三 提供泛型的统一CRUD接口。
    这里摘取几个最常用的CURD方法作为示例

     EntityContext context = new EntityContext(ConfigurationManager.ConnectionStrings["Oracle"].ConnectionString);
                // 新增            
                context.Insert(new Product() { Categoryid = 1, CategoryName = "食品" });
                //查询            
                Product product =  context.GetEntityByKey<Product>(8);
                //修改             
                product.CategoryName ="xxxxx";
                context.Update(product);
                //删除          
                context.Delete(product);
    

      

    四  新增记录时可以返回自增主键(同时支持 SQL Server 和Oracle,oracle需要建序列)

    五 更新记录时可以只修改有改动的字段

             //修改            
            context.PreUpdate(product);
            product.CategoryName ="xxxxx";
                context.Update(product);
    

    五 将查询结果转换为实体集合时使用Emit实现,达到最佳性能。

    List<Product> products = context.Query<Product>("Categoryid=@Categoryid", 1);
    

    六 只需定义简单实体,无需xml定义,无需代码生成,实体特性上无需加入元数据信息,达到使用最简单化。

    七 查询条件参数化,简单明了(参看五的代码)。

    八 事务支持

     try
                {
                    context.BeginTransaction();
                    context.Update(product);
                    context.Delete(product);
                    context.Commit();
                }
                catch (Exception ex)
                {
                    context.Rollback();
                }
    

      

     九 支持扩展数据库支持,只需实现我的解析sql的接口和提供可以执行该sql的data provider即可。

     简单概括就是,配置一个数据库连接,并用该连接实例化一个ObjectContext对象,定义一个与数据库表对应的实体,实体定义无需添加任何特性,便可实现CRUD了,我自认为是最简单易用的ORM,当然我这个orm还有很多人性化的地方,我并没有细细道出,这里只是介绍个大概。各位网友还有什么更好的提议或者更多的想了解的细节,欢迎提出!

    关于网友提到源码和试用的问题,我这里作一个补充说明 暂时提供dll下载,不开放源码,原因如下
    1 框架目前来说完成不久,虽然主体功能都已经有了,但还需要实践检验。
    2 由于是我个人业余时间写的,代码写的比较粗矿,日志跟踪,异常处理之类是基本没有的。。。
    3 将来可能会在工作中使用。

    当然也不排除一段时间,代码成熟以后,朋友们感兴趣的话,我发布源码。
    使用方式很简单,下载dll,引用这两个dll就可以了。如果是oracle,连接字符串参考我的写法,另外需要拷贝
    OraOps11w.dll,Oracle.DataAccess.dll,orannzsbb11.dll,oci.dll,ociw32.dll,oraocci11.dll,oraociei11.dll
    至执行文件的同一个目录下,开发过程中就是debug目录。

     

    至于如何使用问题,其实我上面已经有提及,使用非常简单,以sql server 为例,假设你已经建好表Product(ID,Name,CategoryID),ID是自增列,
    那么项目中引入两个dll后,定义实体 Product :

    public class Product
    {
     public int ID {get;set;}
     public string Name {get;set;}
    public int CategoryID {get;set;}

    }

    调用代码如下
     EntityContext  context = new EntityContext("数据库连接串");
     context.Insert(new Product(){Name="pppp", CategoryID=55});

     如果ID不是自增列,那么在实体在执行插入操作前需要赋值。 

     下载

  • 相关阅读:
    超好看的UI配色网站汇总~
    JS获取非行内样式
    最近看到的一些不错前端面试题目
    指令
    $filter $watch
    学习学习学习
    Mongoose by时间查询
    AngularJs 学习 笔记 4 foreach
    AngularJs 学习 笔记 3
    AngularJs 学习 笔记 2
  • 原文地址:https://www.cnblogs.com/lindping/p/ORM.html
Copyright © 2020-2023  润新知