GitHub开源:升讯威 SQLite 增强组件 Sheng.SQLite.Plus
Github:https://github.com/iccb1013/Sheng.SQLite.Plus
Sheng.SQLite.Plus 是一个对直接使用 ADO.NET 方式操作 SQLite 数据库的一个增强组件,它的操作方式介于 Entity Framework 和 ADO.NET 之间,是用于 SQLite 的高度自由和高开发效率的数据库访问层组件。
+ 支持所有 ADO.NET 原生操作
+ 由开发人员定义模型并解除与数据库表一一对应的关系,可由开发人员灵活指定映射关系。同一张表可以对应到多个不同的模型。
+ 支持直接使用 SQL 语句并根据查询结果在内存中动态映射数据到模型。
+ 在批量操作数据时,支持自动化的事务处理,可自动回滚。
+ 支持一对多的映射关系,即一个实体类可以映射到多张表,反之亦可。
+ 支持自动填充/补全数据实体类中的数据,声明模型并给定主键值或其它条件后,可自动填充模型。
+ 支持 DataSet、DataTable、DataRow 多种粒种的内存动态映射,直接从这些数据集合中生成强类型的对象集合。
+ 支持简单 SQL 构造器,支持自动生成简单的无模型映射的 SQL 语句。
+ 支持对实体字段的精细化处理,如将实体对象的任意 Property 标记 JsonAttribute 后,将自动以 Json 格式写入或读取字段。
+ 高性能,高灵活性,高可维护性。
在 Github 上,除了完整源代码之外,还包括了一个简单的演示程序:

现在假定有 User 表,包括四个字段:Id,Name,Age,ExtraInfo。
我们定义一个简单的 User 类。(亦可使用其它工具自动生成)。
public class User
{
public Guid Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public string ExtraInfo
{
get;
set;
}
}
初始化 Sheng.SQLite.Plus 核心类 DatabaseWrapper,
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["sqlite"].ConnectionString;
DatabaseWrapper database = new DatabaseWrapper(connectionString);
一、简单数据操作
1.插入一条数据:
public void AddUser(User user)
{
_dataBase.Insert(user);
}
Sheng.SQLite.Plus 的 Insert 方法原型是:
public bool Insert(object obj)
Insert 方法会自动解析传入的对象实例,分析对象的类型名称(User)及其所包括的属性(Property),自动实现对 User 表及各字段的动态映射,将数据插入到表中。
2.查询数据
public List<User> GetUserList()
{
return _dataBase.Select<User>();
}
此处原理同上文一样,Select 方法自动解析对象类型,得到表,字段信息,实现数据的查询与填充。
3.修改数据
public void UpdateUser(User user)
{
_dataBase.Update(user);
}
在 Entity Framework 中,使用跟踪对象实例的变化的方式,Sheng.SQLite.Plus 没有采用这种方式,而是直接根据提交的对象实例,不需要先把对象从数据库中查询出来。
4.删除数据
public void RemoveUser(User user)
{
_dataBase.Remove(user);
}
需要注意的是,使用上文中的简单方式进行修改及删除操作,必须在实体类中指定主键字段:
public class User
{
[Key]
public Guid Id
{
get;
set;
}
......
}
至此我们实现了基本的数据库操作的自动化。
是不是很熟悉,和 Entity Framework 很类似是不是?
二、自定义实体类与数据库表的映射关系
上文中的简单增删改查操作,是根据对象实例得到对象类型从而得到类型名称和属性(Property)集合及他们的名称,那么如果实体类型的名称与数据库表名称并不一样怎么办呢?如果数据实体的属性(Property)与数据库表字段并不一一对应怎么办呢?
在大型项目中,这种情况是经常存在的,对于复杂的数据库表设计,到了业务层,可能会有不同的解释方法,例如我有一张用户表,包含了产品不同维度的信息:基本信息、扩展信息等。到了业务实现层面,我希望展开为两个不同的实体对象进行操作,基本信息对象和扩展信息对象。他们所使用的字段可能不太相同,却又包括了某些共通的字段,如Id,姓名。
如上文所说,Sheng.SQLite.Plus 没有强制的实体类与数据库表的映射关系要求,数据库表中的字段多少与实体类中的属性多少,或者说表中有的,实体类中没有,都没有关系,实体类中有的,通过 Attribute 标记是否映射即可。
1.数据库表名的映射指定
我们定义两个不同的实体类:
[Table("User")]
public class User_BaseInfo
{
[Key]
public Guid Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
[Table("User")]
public class User_ExtraInfo
{
[Key]
public Guid Id
{
get;
set;
}
public string ExtraInfo
{
get;
set;
}
}
只需在类型定义前加上 TableAttribute ,对 User_BaseInfo 或 User_ExtraInfo 类的对像实例进行操作,直接使用上文中的增删改查方法即可。至此我们已经开始解除了实体类与数据库表结果的强关联。
2.数据库表字段的映射指定
此处严格来讲,并非一般 ORM 中针对 数据库表字段 的映射,而是针对 结果集字段 的映射。比如说通过复杂 SQL,存储过程得到的结果集,根本不是数据库中的表。
在某些场景中,实体类中需要额外定义一些属性,用于存储特定信息或实现特定功能,这些数据并不需要进行持久化存储。或是实体类中的属性名称与数据库表字段名称存在不完全相同的情况,如将一张表映射到多个数据实体后,为了区别描述,以及基于复杂查询(SQL,存储过程)得到的结果集中的字段名。
[Table("User")]
public class User_ExtraInfo
{
[Key]
public Guid Id
{
get;
set;
}
[Column("ExtraInfo")]
public string Infomation
{
get;
set;
}
[NotMapped]
public int Count
{
get;
set;
}
}
只需在属性定义前加上 ColumnAttribute 或 NotMapped ,使用上文中的增删改查方法即可实现相应的操作。
3.实体类对数据库表的多对多映射
此功能用于将二维的数据库表(或结果集)进一步强类型化。
在使用一般 ORM 框架时,对于复杂的数据库表结构,常常可以见到非常多的字段定义,但在我们的实际业务中,这些字段可能都有不同的逻辑归属,此外,在开发中,我们可能在数据传递,操作的过程中,希望只传递或公开一部分数据,而不是整个对象进行传递。
public class User
{
[Key]
public Guid Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
[Partial]
public ExtraInfo ExtraInfo
{
get;
set;
}
}
public class ExtraInfo
{
public string ExtraInfo
{
get;
set;
}
}
只需在对象上加上 PartialAttribute ,表示属性的对象是 当前数据集 的一部分字段所表示的子对象。
PartialAttribute 还提供了 FieldRelationship 用来进一步指定映射关系。
这样我们实现了实体类对数据表(数据集)的多对一映射,那如何实现多对多的映射呢?实际上非常简单,使用SQL,视图,存储过程进行多表查询,结合使用 PartialAttribute 即可。
三、进阶操作
1.高级查询
除了上文中提到的基本 Select<T>() 方法外,Sheng.SQLite.Plus 提供了额外的几个进阶方式进行数据查询。
a) 基本查询
public List<T> Select<T>() where T : class,new()
上文已展示。
b) 附加查询条件
public List<T> Select<T>(Dictionary<string,object> attachedWhere) where T : class,new()
通过 attachedWhere 额外的指定查询条件。Dictionary<string,object> 中的 string 和 object 分别指定字段和字段值。
c) 直接通过 SQL 语句进行查询
public List<T> Select<T>(string sql) where T : class
直接编写 SQL 语句进行数据查询,Select 方法可根据返回的结果集和指定的对象类型进行自动映射,返回强类型对象集合。
可以传递任意能够返回结果集的SQL语句,返回的结果集自动与泛型T匹配,泛型T也不一定就是数据库中的表所映射的对象。
d) 参数化 SQL 语句查询
public List<T> Select<T>(string sql, List<CommandParameter> parameterList) where T : class
进行参数化的 SQL 语句查询,例如:
List<CommandParameter> parameterList = new List<CommandParameter>();
parameterList.Add(new CommandParameter("@extraInfo", "ABC"));
List<User> userList = _dataBase.Select<User>("SELECT * FROM [User] WHERE ExtraInfo = @extraInfo",parameterList);
2.与内存中的 DataSet 进行动态映射
当我们使用存储过程或其它方式得到一个 DataSet 时,Sheng.SQLite.Plus支持对其进行动态映射,根据 DataSet 数据集得到强类型的对象实例或对象实例的集合。
RelationalMappingUnity 类提供了以下方法:
public static List<T> Select<T>(DataSet ds) where T : class
将 DataSet 视为一个完整数据源,从中查找指定对象类型所映射的表名进行实例化。
public static List<T> Select<T>(DataTable dt) where T : class
使用 DataTable 作为唯一数据集,对指定的对象类型进行实例化。
public static T Select<T>(DataRow dr) where T : class
public static object Select(DataRow dr, Type type)
public static object Select(DataRow dr, Type type, Dictionary<string, string> fieldPair)
上面三个方法提供了更细粒度的操作可能,直接从 DataRow 得到一个强类型的对象实例。
3.数据填充
很多时候我们需要根据某个已知条件查询得到对象实例,如我们得到 User 的 Id,希望查询数据库表得到 User 对象,在Sheng.SQLite.Plus中,我们使用 Fill 方法既可。
public bool Fill<T>(object obj) where T : class,new()
public User GetUser(Guid id)
{
User user = new User();
user.Id = id;
if (_dataBase.Fill<User>(user))
return user;
else
return null;
}
Fill 方法返回一个 bool 值,表示是否成功查询并填充了数据。
Fill 方法也有一个高阶重载,可以额外指定查询条件:
public bool Fill<T>(object obj, Dictionary<string, object> attachedWhere) where T : class,new()
4.SQL 语句构造器
有时,我们希望直接通过 SQL 语句实现对数据库表的简单操作,Sheng.SQLite.Plus 提供了一个 SQL 语句构造器,帮助生成 SQL 语句,可以减轻开发人员编写 SQL 语句的工作量和出错的可能性,提高软件工程的质量。
public void AddUser(User user)
{
SqlStructureBuild sqlStructureBuild = new SqlStructureBuild();
sqlStructureBuild.Type = SqlExpressionType.Insert;
sqlStructureBuild.Table = "User";
sqlStructureBuild.AddParameter("Id", user.Id);
sqlStructureBuild.AddParameter("Name", user.Name);
sqlStructureBuild.AddParameter("Age", user.Age);
SqlExpression sqlExpression = sqlStructureBuild.GetSqlExpression();
_dataBase.ExcuteSqlExpression(sqlExpression);
}
ExcuteSqlExpression 方法在执行 SQL 构造器生成的 SqlExpression 对象时,使用的是参数化,强类型的方法进行的。
5.事务
对于连续的数据库操作,Sheng.SQLite.Plus 自动封装为一个事务进行执行,如果执行失败,将自动回滚。
a) 连续写入操作
非常简单,直接使用 Insert 方法插入一个对象集合既可,方法原型如下:
public void InsertList(List<object> objList)
连接的写入操作时,并不要求传入的参数是同样类型的,也就是说可以传入多个不同类似的实体对象,如同时传入User和Order,Sheng.SQLite.Plus也会将其封装为事务执行,要么全部写入成功,要么回滚。
b) 复杂复合操作
对于相对复杂的数据库事务操作,可使用 SQL 语句构造器,分别构造 SqlExpression 对象,将其按执行顺序放入集合中,通过 ExcuteSqlExpression 执行即可。
public void ExcuteSqlExpression(List<SqlExpression> sqlExpressionList)
这种方式执行的多个 SqlExpression 对象,亦封装为事务进行执行。
Github:https://github.com/iccb1013/Sheng.SQLite.Plus
原文:http://blog.shengxunwei.com/Home/Post/5364bf7e-07a8-4daf-b5bd-9bb4645bb739
曹旭升(sheng.c)
QQ:279060597
Email:cao.silhouette@msn.com
@南京
欢迎朋友们加入我们的微信群:

GitHub开源:升讯威 SQLite 增强组件 Sheng.SQLite.Plus的更多相关文章
- GitHub开源:SQLite 增强组件 Sheng.SQLite.Plus
Github:https://github.com/iccb1013/Sheng.SQLite.Plus Sheng.SQLite.Plus 是一个对直接使用 ADO.NET 方式操作 SQLite ...
- GitHub开源:升讯威ADO.NET增强组件 sheng.ADO.NET.Plus V1.3
GitHub: https://github.com/iccb1013/sheng.ADO.NET.Plus 早前分享过,当时没有把代码上传到Github,只是通过邮件的形式分享给了部分需要的朋友,最 ...
- 升讯威ADO.NET增强组件(源码):送给喜欢原生ADO.NET的你
目前我们所接触到的许多项目开发,大多数都应用了 ORM 技术来实现与数据库的交互,ORM 虽然有诸多好处,但是在实际工作中,特别是在大型项目开发中,容易发现 ORM 存在一些缺点,在复杂场景下,反而容 ...
- Github 开源:升讯威 Winform 开源控件库( Sheng.Winform.Controls)
Github 地址:https://github.com/iccb1013/Sheng.Winform.Controls 本控件库中的代码大约写于10年前(2007年左右),难免有不成熟与欠考虑之处, ...
- GitHub开源:升讯威微信营销系统(第三方微信平台)完整源代码
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction 升讯威微信营销系统开发实践系列升讯威微信营销系统开发实践:(1)功能设计与架构设 ...
- Github 开源:使用升讯威 Mapper( Sheng.Mapper)与 AutoMapper 互补,大幅提高开发效率!
Github 地址:https://github.com/iccb1013/Sheng.Mapper 在上一篇幅中,简单介绍了 升讯威 Mapper( Sheng.Mapper)[http://www ...
- 升讯威微信营销系统开发实践:(4)源代码结构说明 与 安装部署说明( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- 升讯威微信营销系统开发实践:(3)功能介绍与此项目推广过程的一些体会( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- 升讯威微信营销系统开发实践:所见即所得的微官网( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
随机推荐
- 第七章——集成学习和随机森林(Ensemble Learning and Random Forests)
俗话说,三个臭皮匠顶个诸葛亮.类似的,如果集成一系列分类器的预测结果,也将会得到由于单个预测期的预测结果.一组预测期称为一个集合(ensemble),因此这一技术被称为集成学习(Ensemble Le ...
- LESS的好处
今日目标: 1:今天的学习内容是在工作完成的情况下,学习Less(之所以学习Less是因为项目中使用的是Less)-------------当前进度(0%) 注意项: 务必确保在 less.js 之前 ...
- oracle+mybatis 使用动态Sql在要insert的字段不确定的情况下实现批量insert
最近做项目遇到一个挺操蛋的问题,由于业务的关系,DB的数据表无法确定,在使用过程中字段可能会增加,这样在insert时给我造成了很大的困扰. 先来看一下最终我是怎么实现的: <insert id ...
- css中的单冒号和双冒号
最近突然被别人问起css单冒号和双冒号有什么区别,答曰:"不知道". 虽然还在填坑中,但作为一个跨过了初级的FEer,感觉着实汗颜,刚好今天下午在搜别的问题的时候,突然看到一个对比 ...
- [Linux]Linux 下的 Docker 安装与使用
一.安装与配置 1.设置阿里云镜像源 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/cen ...
- [USACO11JAN]大陆议会The Continental Cowngress_2-sat
[USACO11JAN]大陆议会The Continental Cowngress_2-sat 题意: 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会. 议会以“每头 ...
- Windows Ubuntu Bash申请免费通配符证书(Let's Encrypt)并绑定IIS
什么是 Let’s Encrypt? 部署 HTTPS 网站的时候需要证书,证书由 CA 机构签发,大部分传统 CA 机构签发证书是需要收费的,这不利于推动 HTTPS 协议的使用. Let’s En ...
- 安卓开发笔记(二十八):仿写IOS switch选择器控件实现,checkbox
我们先来看看效果: 这里我们主要使用了github上的一个开源项目,配置起来比较方便,下面解释一下该如何使用:首先是:Gradle文件当中进行配置: dependencies { implementa ...
- Axure RP8 注册码
升级了 8.1.0.3381版本后,需要使用下面这组注册码 License:zdfansKey:fZw2VoYzXakllUuLVdTH13QYWnjD6NZrxgubQkaRyxD5+HNMqdr+ ...
- hive新建分区表
hive新建分区表语句如下: create table table_name (col1_name string comment '备注1', col2_name string comment '备注 ...