随笔 - 35  文章 - 0  评论 - 121  阅读 - 56623

不要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不是自增列,那么在实体在执行插入操作前需要赋值。 

 下载

posted on   lindping  阅读(3603)  评论(37编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
< 2012年5月 >
29 30 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 1 2
3 4 5 6 7 8 9

点击右上角即可分享
微信分享提示