FreeSql 是 .NetFramework 4.6+、.NetCore 下的 ORM 功能库,提供了丰富的功能,支持五种流行数据库 MySql/SqlServer/PostgreSQL/Oracle/Sqlite。

正常的数据库都支持跨库,然而 Sqlite 默认不支持,或者说支持起来较为麻烦,FreeSql 最关心的是通用、易用性,本文介绍 FreeSql 如何实现 Sqlite 跨库操作。

故事发生在 CodeFirst 自由开发

FreeSql 支持并推荐使用 CodeFirst 方式开发项目,这种开发方式非常自由,如同 FreeSql 的命名一般。

如下定义两个实体(文章、评论):

class Topic {
public Guid Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreateTime { get; set; }
}
[Table(Name = "xxxtb.Comment")]
class Comment {
public Guid Id { get; set; }
public Guid TopicId { get; set; }
public Topic Topic { get; set; }
public string Nickname { get; set; }
public string Content { get; set; }
public DateTime CreateTime { get; set; }
}

我们希望将 Topic 的数据存到主库,Comment 的数据存到别外一个库(xxxtb)。比如使用 mysql,不指定数据库情况下,将操作当前数据库下的表。

其他 ado.net 或 ORM 将面临的问题(默认情况下):

1、驱动只打开了一个库,或者需要手工调用驱动的方法对其他库进行附加;

2、项目中可能需要定义多个 orm,实现对多个数据库的存储和查询;

3、无法使用跨库联表查询;

解决用户使用问题

使用习惯是 FreeSql 主要攻克的难题,其他数据库都行,【吐槽】就你丫的 Sqlite 奇葩,同连接下默认做不到跨库操作(或者说使用不方便)。

好在如今的 .NET 库大多数都已经开源,于是翻阅 System.Data.SQLite.Core 源码做了总结:

SQLiteConnection 连接对象在 Open 后,执行如下命令可附加多个数据库;

attach database [xxxtb.db] as [xxxtb];

于是,

第一步:实现一个扩展方法,使用 OpenAndAttach 代替 Open:

public static void OpenAndAttach(this DbConnection that, string[] attach) {
that.Open(); if (attach?.Any() == true) {
var sb = new StringBuilder();
foreach(var att in attach)
sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); var cmd = that.CreateCommand();
cmd.CommandText = sb.ToString();
cmd.ExecuteNonQuery();
}
}
//异步方法的实现省略...

第二步:增加 ConnectionString 参数 Attachs

Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10

第三步:SqliteConnectionPool 实施

1、解析 Attachs;

var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
if (att.Length == 2) {
//此条件说明存在,找到 Attachs 配置的值,并且它支持以逗号分割
var idx = att[1].IndexOf(';');
Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(',');
}

2、将原有 Open 方法替换成 OpenAndAttach;

大功告成

编码与实施过程完成,接下来测试结果,仍然使用上方给出的两个实体类型。

static IFreeSql sqlite = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10")
.UseAutoSyncStructure(true)
.UseLazyLoading(true)
.Build(); //秀一波 FreeSql.Repository 扩展包
//安装方法:dotnet add package FreeSql.Repository
var topicRepository = sqlite.GetGuidRepository<Topic>();
var commentRepository = sqlite.GetGuidRepository<Comment>(); //添加测试文章
Guid topicId = FreeUtil.NewMongodbId();
topicRepository.Insert(new Topic {
Id = FreeUtil.NewMongodbId(),
Title = "文章标题1",
Content = "文章内容1",
CreateTime = DateTime.Now
}); //添加10条测试评论
var comments = Enumerable.Range(0, 10).Select(a => new Comment {
Id = FreeUtil.NewMongodbId(),
TopicId = topicId,
Nickname = $"昵称{a}",
Content = $"评论内容{a}",
CreateTime = DateTime.Now
});
var affrows = commentRepository.Insert(comments); var find = commentRepository.Select.Where(a => a.Topic.Title == "文章标题1").ToList();
//SELECT a."Id", a."TopicId", a."Nickname", a."Content", a."CreateTime"
//FROM "xxxtb"."Comment" a, "Topic" a__Topic
//WHERE (a__Topic."Title" = '文章标题1') //find 查询出了10条数据

然后我们使用 navicat 附加两个数据库查看:

其他说明

1、FreeUtil.NewMongodbId 是生成有序的 Guid 值,在 FreeSql 中实现,其实可以使用 Guid.NewGuid,这里我承认有秀的嫌疑;

2、文章中的代码没有过多的依赖,在 vs2017+.netcore2.2 测试一次运行通过,sqlite 的优势免安装服务;

3、FreeSql 支持 CodeFirst,即建好实体运行程序,表就会创建;

4、FreeSql.Repository 是扩展包,实现通用 CURD 仓储层功能,文档:https://github.com/2881099/FreeSql/wiki/Repository

这个功能其实在 FreeSql 早期就已经实现了,但是一直没能有时间将过程经验整理成文章,今天把文章写完写全,希望能给大家带来一点“惊吓”。FreeSql还有更多细节优化并不是路人一眼能看透,如果觉得写得不错麻烦点个赞,这也是我继续写下去的源动力。

一遍看不明白的话,建议多看几遍。谢谢观看!

FreeSql 如何实现 Sqlite 跨库查询的更多相关文章

  1. 如何使用SQL SERVER数据库跨库查询

    SQL Server中内置了数据库跨库查询功能,下面简要介绍一下SQL Server跨库查询.首先打开数据源码:OPENDATASOURCE不使用链接的服务器名,而提供特殊的连接信息,并将其作为四部分 ...

  2. SqlServer跨库查询

    由于业务的拆分,数据库拆分为两种作用: 汇总数据库(Master,头节点数据库), 子节点数据库(Compute Node,计算子节点数据库) 这样,就设计到子节点访问头节点数据库中的某张汇总表,这种 ...

  3. ACCESS-如何多数据库查询(跨库查询)

    测试通过:ACCESSselect * from F:\MYk.mdb.tablename说明:1.查询语句2.来原于哪(没有密码是个路径)3.查询的表名 ====================== ...

  4. Access数据库跨库查询及记录集区分

    医疗设备软件一般都是单机软件,如果是Windows平台,常会选择Access数据库存储结构化数据,因为他轻量,便于部署.然而随着医疗信息化的发展,医生希望对多台单机设备的数据进行管理,采用网络数据库当 ...

  5. EF 跨库查询

    原因:最近公司项目,遇到一个ef跨库查询的问题.(只是跨库,并不是跨服务器哈) 主要我们的一些数据,譬如地址,城市需要查询公共资料库. 但是本身我的程序设计采用的是ef框架的.因此为这事花费了1天时间 ...

  6. SQL Server 跨库查询

    1. 开启Ad Hoc Distributed Queries组件,在sql查询编辑器中执行如下语句: reconfigure reconfigure 2. 跨库查询操作 select * from ...

  7. 跨库查询(OpenDataSource)与链接服务器(Linking Server)

    一:跨库查询 Openrowset/opendatasource() is an ad-hoc method to access remote server's data. So, if you on ...

  8. mysql 跨库查询问题

    MySQL实现跨服务器查询 https://blog.csdn.net/LYK_for_dba/article/details/78180444 mysql> create database l ...

  9. SQLServer跨库查询--分布式查询

    出处:http://www.cnblogs.com/doosmile/archive/2012/03/16/2400646.html --用openrowset连接远程SQL或插入数据 --如果只是临 ...

随机推荐

  1. webpack的css压缩不兼容IOS8问题探索

    webpack使用postcss的autoprefixer插件,并在压缩css时使用了cssnano,处理不当的情况下会导致压缩css后,部分兼容前缀(比如-webkit-)被删除的问题. postc ...

  2. Java 算法(二)

    [程序9] 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数 //第一种public class A09 {publi ...

  3. 基于ASP.NET MVC 微信网页登录授权(scope为snsapi_base) 流程 上 获取OPENID

    流程图 我们需要判断是否存在OPENID  首先我们得先定义一个全局的OPENID 类似于普通账号密码登录系统的 当前登录用户ID  因为我是MVC 框架  我这里定义一个控制器基类 BaseCont ...

  4. js基础进阶--编的实用技巧(一)

    我的个人博客:http://www.xiaolongwu.cn 在平时的开发中,编码技巧很重要,会让你少写很多代码,起到事倍功半的效果. 下面总结几种简单的技巧,大家共同学习一下 1. 利用+.-./ ...

  5. Angular使用总结 ---以密码确认为例实现模版驱动表单的自定义校验

    上一篇 总结了模版驱动表单的基本用法,示例中的校验使用的是原生HTML5的校验方式,本文补上自定义校验的部分. HTML5原生的表单校验属性(必填,长度限制,取值间隔,正则表达式等等)可以满足普通的校 ...

  6. Spring Boot使用RestTemplate消费REST服务的几个问题记录

    我们可以通过Spring Boot快速开发REST接口,同时也可能需要在实现接口的过程中,通过Spring Boot调用内外部REST接口完成业务逻辑. 在Spring Boot中,调用REST Ap ...

  7. PHP 的 uniqid 函数产生的 id 真的是唯一的么?

    PHP 的 uniqid 函数产生的 id 真的是唯一的么? 最近使用到了 uniqid,就产生了疑问?uniqid 生成的 id 由什么组成?真的是唯一的么?什么情况下会产生冲突? 从文档中看到 u ...

  8. C++/C实现各种排序算法(持续更新)--冒泡排序,选择排序,归并排序

    2018 3 17 今日总结一下C++中的排序算法: 1冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是 ...

  9. 这样入门asp.net core,如何

    本文章主要说明asp.net core的创建和简单使用. 一.使用到的命令 dotnet new :创建项目(解决方案,类库,单元测试等),如:dotnet new web dotnet add pa ...

  10. 剑指offer(javascript实现)

    1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. funct ...