Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案。Aoite.Data 适用于市面上大多数的数据库提供程序,通过统一封装,可以在日常开发中简单便捷的操作数据库。

【Aoite 系列 目录】

没有使用 Aoite 之前是这样的:

当你使用 Aoite 以后是这样的:

hah~~~你还不赶紧加入 Aoite GitHub 的大家庭吧!!

1. 快速入门

本小节将会使用 Microsoft SQL Server Compact 数据库作,一步一步的讲解针对数据库的增删改查。

1.1 首先,我们需要创建一个实体

class SimpleUser
{[Column(true /* isPrimaryKey */)]public string Username { get; set; }public string Password { get; set; }public string Memo { get; set; }public override string ToString(){return "Username:{0}\tPassword:{1}\tMemo:{2}".Fmt(this.Username, this.Password, this.Memo ?? "<NULL>");}
}

实体的主键必须通过 Aoite.Data.ColumnAttribute 指定,若找不到此特性,框架还会尝试找到 Id 属性。若以上条件均不满足,操作过程中便可能直接抛出错误。

1.2 创建一个数据库引擎

var dbPath = GA.FullPath("Sample01.sdf");
if(File.Exists(dbPath)) File.Delete(dbPath);MsSqlCeEngine engine = new MsSqlCeEngine(dbPath, null /* password*/);
engine.CreateDatabase();

1.3 通过代码,创建一张表

engine.Execute(@"CREATE TABLE [SimpleUser]"+ "([Username] nvarchar(50) NOT NULL PRIMARY KEY"+ ", [Password] nvarchar(50) NOT NULL"+ ", [Memo] nvarchar(500))").ToNonQuery()           /* 执行查询命令,并返回受影响的行数结果。 */.ThrowIfFailded();      /* 如果这个 SQL 语句出现异常,则直接抛出。 */

ToNonQuery:方法的内部原理是执行 DbCommand.ExecuteNonQuery,一般的新增、删除、修改等操作均可用此方法。

ThrowIfFailded:任何方法的调用都会有一个 Result(结果),而这个结果包含了 Value(值)、Status(状态码)和Message(消息)。ThrowIfFaildedUnsafeValue 的作用一致,在结果捕获到错误时,将会直接抛出异常。

通常定义 Result 的方法里,是不会直接抛出业务逻辑上的异常。方法的内部自然会包装好的这个异常,再返回给调用方。也就是说,返回的数据类型若是继承 System.Result,表示这个方法具有业务容错性

1.4 基本工作已完成。现在我们试着往数据库添加一条新纪录

engine.Add(new SimpleUser { Username = "admin", Password = "123456" }).ThrowIfFailded();Console.WriteLine("Add -> {0}", engine.FindOne<SimpleUser>("admin").UnsafeValue);

Add:这是一个扩展方法,通过高性能的反射,将对应的实体生成 INSERT 语句。

FindOne:这也是一个扩展方法,默认情况下是根据 Primary Key 去查找一条记录。

对于添加对象,还要介绍一种非常好用的方式,匿名方式:

engine.AddAnonymous<SimpleUser>(new { Username = "admin", Password = "123456" }).ThrowIfFailded();

这样两种添加方式有什么区别吗?有!第一个生成的是完整的 INSERT 语句(包括 Simple.Memo),而 AddAnonymous 的 INSERT 语句不含 Simple.Memo

1.5 通过匿名方式,你还可以这样修改对象

engine.ModifyAnonymous<SimpleUser>(new { Username = "admin", Memo = "haha" }).ThrowIfFailded();

匿名方式用于非常多的场景,最常见的比如:修改用户的密码,如果有 Modify,那么表里的这条记录所有数据都会被覆盖,而通过 ModifyAnonymous 方法,可以简单的 new { Id = id, Password = passowrd } 来生成更加简短的 UPDATE 语句。

同样,删除的时候,可以通过 RemoveAnonymous 删除指定主键的记录。

engine.RemoveAnonymous<SimpleUser>("admin").ThrowIfFailded();

你看,Aoite.Data 就是这么任性、好用、简单

2. 上下文

显然,Aoite.Data 肯定不仅仅只有上个小节的那些内容。

上下文是 Aoite.Data 一个重要的概念。上个小节的所有执行的生命周期是这样的:

倘若采用以下代码进行数据库操作,将会极大的浪费数据库资源:

var r1 = engine.Execute("sql1.....").ToNonQuery();
var r2 = engine.Execute("sql2.....").ToNonQuery();
var r3 = engine.Execute("sql3.....").ToNonQuery();
var r4 = engine.Execute("sql4.....").ToNonQuery();

显然,这种方式弱爆了。对于有严重开发洁癖的我们,怎能忍受这种代码呢?所以,上下文的目的是实现一次打开连接,多次执行,最后关闭连接,从而达到节省数据库连接池资源。可以通过以下方式:

using(var context = engine.Context)
{//- context.Open(); 此句可以节省,在第一次执行命令时,如果连接还未打开,将会自动打开连接。var r1 = context.Execute("sql1.....").ToNonQuery();var r2 = context.Execute("sql2.....").ToNonQuery();var r3 = context.Execute("sql3.....").ToNonQuery();var r4 = context.Execute("sql4.....").ToNonQuery();//- using 释放时,将会自动关闭,从而保证无论在哪一种情况(哪里系统崩溃)下都可以关闭连接。
}

开启事务有三种方式:

  • context.OpenTransaction():手工开启事务。
  • using (var context = engine.ContextTransaction):指定当前范围内都是采用事务。
  • System.Transactions.TransactionScope

当然了,最重要的是,事务的结束之前,我们必须调用 context.Commit() 来提交事务,否则整个事务将会被丢弃。若希望手工回滚的话,可以调用 context.Rollback()

示例

我们紧接着前面的示例代码,采用上下文批量添加 10 条记录:

using(var context = engine.Context)
{for(int i = 0; i < 10; i++){context.Add(new SimpleUser { Username = "user" + i, Password = "123456" }).ThrowIfFailded();Console.WriteLine("数据库 RowCount -> {0}", engine.RowCount<SimpleUser>());Console.WriteLine("上下文 RowCount -> {0}", context.RowCount<SimpleUser>());}
}

上方代码输出如下所示:

数据库 RowCount -> 1
上下文 RowCount -> 1
数据库 RowCount -> 2
上下文 RowCount -> 2
数据库 RowCount -> ...
上下文 RowCount -> ...
数据库 RowCount -> 10
上下文 RowCount -> 10

我们来试着查询所有记录:

foreach(var item in engine.FindAllWhere<SimpleUser>().UnsafeValue)
{Console.WriteLine(item);
}

FindAllWhere:根据指定筛选条件,查询指定泛型表的所有记录。

而采用事务的代码:

using(var context = engine.ContextTransaction)
{for(int i = 10; i < 20; i++){context.Add(new SimpleUser { Username = "user" + i, Password = "123456" }).ThrowIfFailded();Console.WriteLine("数据库 RowCOUNT -> {0}", engine.RowCount<SimpleUser>());Console.WriteLine("上下文 RowCOUNT -> {0}", context.RowCount<SimpleUser>());}Console.WriteLine("事务提交前 数据库 RowCOUNT -> {0}", engine.RowCount<SimpleUser>());context.Commit().ThrowIfFailded();Console.WriteLine("事务提交后 数据库 RowCOUNT -> {0}", engine.RowCount<SimpleUser>());
}

以上代码的输出:

使用事务上下文...
数据库 RowCOUNT -> 10
上下文 RowCOUNT -> 11
数据库 RowCOUNT -> 10
上下文 RowCOUNT -> 12
数据库 RowCOUNT -> 10
上下文 RowCOUNT -> ...
数据库 RowCOUNT -> 10
上下文 RowCOUNT -> 20
事务提交前 数据库 RowCOUNT -> 10
事务提交后 数据库 RowCOUNT -> 20

3. 结束

关于 Aoite.Data 的简单介绍,就到此结束了,如果你喜欢这个框架,不妨点个推荐吧!如果你非常喜欢这个框架,那请顺便到Aoite GitHub Star 一下 :)

点此下载本文的所有示例代码。

问答:

  1. 是否开源:当然
  2. 单元测试:当然。覆盖率没达到 100%,但基本上 80% 的逻辑都有了单元测试。
  3. 有商用项目案例吗:!如:亚XXX得综合管理系统、亚XXX得门店系统、短信删除助手、XX通讯录(擦,这个名字我忘了)、店X宝虚拟充值平台、店X宝O2O商城、遛XXX电子商城……很多。
  4. 为什么现在不支持 ORACLE 或 Mysql 等数据库:支持。具体可参考 Aoite.Data 的前身 Sofire.Data。只不过现在为了将 Aoite.dll 瘦身,这些功能可以通过简单扩展可以快速的实现……

转载于:https://www.cnblogs.com/sofire/p/aoite_data.html

Aoite 系列(01) - 比 Dapper 更好用的 ORM相关推荐

  1. PHP扩展开发系列01 - 我要成为一名老司机

    PHP扩展开发系列01 - 我要成为一名老司机 1. 关于扩展的教程貌似挺全了,为啥还写? 记录下我写扩展的历程 自认为会写的更容易理解 我的宗旨就是 "先用再识" 代码写着写着就 ...

  2. vSphere 7 With Kubernetes系列01:随想

    vSphere 7 With Kubernetes系列01:随想 原创 李严省 虚实之路 7月28日 收录于话题 #vSphere with K8s 9个 大家好,好久不见,公众号停更差不多快有1年的 ...

  3. LLM系列 | 01: 亲测ChatGPT最强竞品Claude,且无需翻墙、注册简单、免手机号

    简介 春风桃李花开日,秋雨梧桐叶落时.小伙伴好,我是微信公众号<小窗幽记机器学习>的小编:卖核弹的小女孩.更多.更新文章欢迎关注微信公众号:小窗幽记机器学习.后续会持续整理模型加速.模型部 ...

  4. 【R语言系列01】烦人的拼贴操作 详述 paste and paste0

    R语言系列01 烦人的拼贴操作 paste 与 paste0 相信很多人在一开始使用R语言的paste, paste0的时候,总是拿捏不准,感到有些迷糊. 本期文章中,我将记录对比一些操作以及表现,加 ...

  5. 【Web前端学习系列01】—HTML

    [Web前端学习系列01]-HTML HTML 基本标签-head head title标签 meta标签 link标签 style标签 script标签 base标签 文本 标题标签 h 段落标签 ...

  6. 战舰V3适配oneos系列01:bsp适配

    战舰V3适配oneos系列01:bsp适配 本系列以oneos2.3.0提供的STM32F103ZE模板为基础,将oneos在战舰V3上运行起来,并逐步适配相关外设 本系列计划周更 本系列相关代码将上 ...

  7. python ai 教学_【Python AI教学】从零开始学Python AI开发系列01

    原标题:[Python AI教学]从零开始学Python AI开发系列01 欢迎开启新的旅程. 从2016年开始,AI人工智能的热潮扑面而来.而在机器学习和深度学习领域,Python位于最受欢迎的编程 ...

  8. 【安全利器SELinux快速入门系列 | 01】SELinux基础入门

    这是机器未来的第35篇文章 原文首发地址:https://blog.csdn.net/RobotFutures/article/details/125914553 文章目录 1. 研究目标 2. se ...

  9. JavaScript进阶系列01,函数的声明,函数参数,函数闭包

    本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...

最新文章

  1. 《QTP自动化测试进阶》(1)
  2. android 蓝牙 setscanmode,蓝牙LE扫描在后台无法在Android M上运行
  3. 奖学金pascal程序
  4. Algorithm of permutation(全排列算法)
  5. python蒙特卡洛模拟_基于Python的21点游戏蒙特卡洛模拟
  6. Tensorflow——会话
  7. 使用 PowerShell 自动登录 Azure
  8. 维吉尼亚密码原理详解及算法实现
  9. 中职计算机平面设计主要学什么,四川省计算机平面设计专业学什么
  10. 必看!云桌面与传统PC六项成本对比
  11. React学习笔记003-内外联样式
  12. BZOJ3894: 文理分科
  13. 语料库数据处理个案实例(分词和分句、词频统计、排序)
  14. 6 月份最火的 10 个 GitHub 项目
  15. 新项目实操分析,用付费视频进行流量变现
  16. csdn 头衔 创作者 博客专家
  17. embedv.php_微信开发在线点播电影网ckplayer播放器实例介绍
  18. 关于地图偏移问题的解答
  19. charles手机抓包教程
  20. 【教学类-15-03】20221119《姓名描字帖-A4竖版(1*7笔画复杂大字)》(大班适合中层次幼儿)

热门文章

  1. [概率][lca][dfs][树形dp] Jzoj P4225 宝藏
  2. ruby中数组的常用函数
  3. 图像视频处理中Win7 32位+VS2010+OpenCV2.3.1的配置过程
  4. Decoders Matter for Semantic Segmentation: Data-Dependent Decoding Enables Flexible Feature Aggregat
  5. VS远程Linux项目附加pthread
  6. Labview子VI的创建与调用
  7. 【RobotStudio学习笔记】(五)工具数据
  8. 【OpenCV】基本数据类型
  9. python 多态 锁_python 上下文管理器,多态,数据锁定与自省,
  10. android fragment 教程,Android app开发中的Fragment入门学习教程