不要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不是自增列,那么在实体在执行插入操作前需要赋值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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的设计模式综述