(四)数据持久化(基于YesSql)
ORM框架(持久化流程)
session是事务 (transaction) 的工厂,处理session后,所有更改将自动刷新到数据库中。或者,如果要处理何时将更改刷新到数据库,即transaction将在session处理完后异步提交。session也可以取消事务。
新建两个项目,Data 与 Data.Abstractions, 其中 Data.Abstractions 为对外抽象接口(面向对象设计原则),并用Nuget添加程序包。
public interface IFeatureInfo { string Id { get; } string Name { get; } int Priority { get; } string Category { get; } string Description { get; } bool DefaultTenantOnly { get; } //IExtensionInfo Extension { get; } string[] Dependencies { get; } }
public interface IFeatureManager { IEnumerable<IFeatureInfo> GetFeatures(); IEnumerable<IFeatureInfo> GetFeatures(string[] featureIdsToLoad); IEnumerable<IFeatureInfo> GetFeatureDependencies(string featureId); IEnumerable<IFeatureInfo> GetDependentFeatures(string featureId); IFeatureInfo GetFeatureForDependency(Type dependency); void TryAdd(Type type, IFeatureInfo feature); }
public class DatabaseProvider { public string Name { get; set; } public string Value { get; set; } public bool HasConnectionString { get; set; } public bool HasTablePrefix { get; set; } publi
/// <summary> /// 数据库迁移管理 /// </summary> public interface IDataMigrationManager { /// <summary> ///返回具有至少一个数据迁移类的特性,并调用相应的升级方法 /// </summary> Task<IEnumerable<string>> GetFeaturesThatNeedUpdateAsync(); /// <summary> /// 运行所有需要更新的迁移。 /// </summary> Task UpdateAllFeaturesAsync(); /// <summary> /// 将数据库更新为指定功能的最新版本 /// </summary> Task UpdateAsync(string feature); /// <summary> /// 将数据库更新为指定功能的最新版本 /// </summary> Task UpdateAsync(IEnumerable<string> features); /// <summary> /// 执行脚本删除与该特性相关的任何信息 /// </summary> /// <param name="feature"></param> Task Uninstall(string feature); }
public interface IDbConnectionAccessor { /// <summary> /// 创建数据库连接 /// </summary> /// <returns></returns> DbConnection CreateConnection(); }
/// <summary> /// 数据库迁移工具,封装YesSql功能,直接修改数据库结构 /// </summary> public interface ISchemaBuilder { YesSql.Sql.ISchemaBuilder SchemaBuilder { get; set; } }
public static class DataAccess { public static IApplicationBuilder UseDataAccess(this IApplicationBuilder app) { return app.UseMiddleware<CommitSessionMiddleware>(); } /// <summary> /// 添加数据库 /// </summary> /// <param name="services"></param> /// <param name="databaseType">数据库类型,支持:SqlConnection,Sqlite,MySql,Postgres</param> /// <param name="connectionString">Sqlite为yessql.db文件所在路径,其他数据库为连接字符串</param> /// <param name="tablePrefix">表名前缀</param> /// <returns></returns> public static IServiceCollection AddDataAccess(this IServiceCollection services, string databaseType, string connectionString, string tablePrefix = null) { services.AddScoped<IDataMigrationManager, DataMigrationManager>(); // Adding supported databases services.TryAddDataProvider(name: "Sql Server", value: "SqlConnection", hasConnectionString: true, hasTablePrefix: true, isDefault: false); services.TryAddDataProvider(name: "Sqlite", value: "Sqlite", hasConnectionString: false, hasTablePrefix: false, isDefault: true); services.TryAddDataProvider(name: "MySql", value: "MySql", hasConnectionString: true, hasTablePrefix: true, isDefault: false); services.TryAddDataProvider(name: "Postgres", value: "Postgres", hasConnectionString: true, hasTablePrefix: true, isDefault: false); // Configuring data access services.AddSingleton<IStore>(sp => { IConfiguration storeConfiguration = new YesSql.Configuration(); switch (databaseType) { case "SqlConnection": storeConfiguration .UseSqlServer(connectionString, IsolationLevel.ReadUncommitted) .UseBlockIdGenerator(); break; case "Sqlite": var databaseFolder = connectionString; var databaseFile = Path.Combine(databaseFolder, "yessql.db"); Directory.CreateDirectory(databaseFolder); storeConfiguration .UseSqLite($"Data Source={databaseFile};Cache=Shared", IsolationLevel.ReadUncommitted) .UseDefaultIdGenerator(); break; case "MySql": storeConfiguration .UseMySql(connectionString, IsolationLevel.ReadUncommitted) .UseBlockIdGenerator(); break; case "Postgres": storeConfiguration .UsePostgreSql(connectionString, IsolationLevel.ReadUncommitted) .UseBlockIdGenerator(); break; default: throw new ArgumentException("Unknown database type: " + databaseType); } if (!string.IsNullOrWhiteSpace(tablePrefix)) { storeConfiguration = storeConfiguration.SetTablePrefix(tablePrefix + "_"); } var store = StoreFactory.CreateAsync(storeConfiguration).GetAwaiter().GetResult(); var indexes = sp.GetServices<IIndexProvider>(); store.RegisterIndexes(indexes); return store; }); services.AddScoped(sp => { var store = sp.GetService<IStore>(); if (store == null) { return null; } var session = store.CreateSession(); var scopedServices = sp.GetServices<IIndexProvider>(); session.RegisterIndexes(scopedServices.ToArray()); var httpContext = sp.GetRequiredService<IHttpContextAccessor>()?.HttpContext; if (httpContext != null) { httpContext.Items[typeof(YesSql.ISession)] = session; } return session; }); services.AddTransient<IDbConnectionAccessor, DbConnectionAccessor>(); return services; } } public class CommitSessionMiddleware { private readonly RequestDelegate _next; public CommitSessionMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { await _next.Invoke(httpContext); // Don't resolve to prevent instantiating one in case of static sites var session = httpContext.Items[typeof(YesSql.ISession)] as YesSql.ISession; if (session != null) { await session.CommitAsync(); } } }
public static class DataProvider { public static IServiceCollection TryAddDataProvider(this IServiceCollection services, string name, string value, bool hasConnectionString, bool hasTablePrefix, bool isDefault) { for (var i = services.Count - 1; i >= 0; i--) { var entry = services[i]; if (entry.ImplementationInstance != null) { var databaseProvider = entry.ImplementationInstance as DatabaseProvider; if (databaseProvider != null && String.Equals(databaseProvider.Name, name, StringComparison.OrdinalIgnoreCase)) { services.RemoveAt(i); } } } services.AddSingleton(new DatabaseProvider { Name = name, Value = value, HasConnectionString = hasConnectionString, HasTablePrefix = hasTablePrefix, IsDefault = isDefault }); return services; } }
(四)数据持久化(基于YesSql)的更多相关文章
- python(四)数据持久化操作 文件存储
1.写入 导入pickle包 然后组织一个列表my_list,保存为pkl格式,可以是任意格式 在磁盘下回出现一个保存的文件 2.读取
- iOS中常用的四种数据持久化技术
iOS中的数据持久化方式,基本上有以下四种:属性列表 对象归档 SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults st ...
- iOS中常用的四种数据持久化方法简介
iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...
- 四种数据持久化方式(下) :SQLite3 和 Core Data
在上文,我们介绍了iOS开发中的其中2种数据持久化方式:属性列表.归档解档. 本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文 ...
- 几种.NET平台数据持久化框架介绍
原文连接:http://yuxnet.blog.163.com/blog/static/164863495201131532223362/ 在.NET平台下,关于数据持久层框架非常多,本文主要对如下几 ...
- iOS数据持久化-OC
沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...
- iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)
本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...
- iOS: 数据持久化方案
数据持久化方案(如果总结不到位,或者有误的地方,敬请斧正) 一.功能: 主要是将数据持久化到本地,减少对网络请求的次数,既节省了用户的流量,也增强了App的体验效果. 二.种类: plist存储:使 ...
- 深入理解iPhone数据持久化(手把手教你iphone开发 – 基础篇)
在所有的移动开发平台数据持久化都是很重要的部分:在j2me中是rms或保存在应用程序的目录中,在symbian中可以保存在相应的磁盘目录中和数据库中.symbian中因为权限认证的原因,在3rd上大多 ...
- docker-compose一键部署redis一主二从三哨兵模式(含密码,数据持久化)
本篇基于centos7服务器进行部署开发 一.拉取redis镜像,使用如下命令 docker pull redis 1.查看镜像是否拉取成功,使用如下命令 docker images 显示如下则证明拉 ...
随机推荐
- java练习---8
//程序员:罗元昊 2017.10.16 题目3.7 import java.util.Scanner; public class L { @SuppressWarnings("resour ...
- 滚动视图、列表视图[ListView、SimpleAdapter类]
滚动视图 <ScrollView android: layout_width="fill_parent" android: layout_height="fill_ ...
- Divide and Conquer
1 2 218 The Skyline Problem 最大堆 遍历节点 public List<int[]> getSkyline(int[][] buildings) { ...
- 关于STM32F103+ESP8266+阿里云过程之修改SDK支持UART和SmartConfig(四)
设备上报状态到阿里云成功之后,还要接受来至云端下发的命令,如APP.在ESP8266接受到数据之后可将数据先进行解析,再通过自定义协议与STM32进行串口通讯,也可以将接收到的数据中的信息直接传输到U ...
- spring 的权限控制:security
下面我们将实现关于Spring Security3的一系列教程. 最终的目标是整合Spring Security + Spring3MVC 完成类似于SpringSide3中mini-web的功能. ...
- Cassandra之Docker环境实践
Cassandra简介 Cassandra是一个开源分布式NoSQL数据库系统. 它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon D ...
- Java虚拟机学习笔记(三)--- 生存还是死亡
即便是可达性分析中不可达的对象,也不代表该对象一定被回收,一个对象被“宣判死刑”需要经过两次标记,第一次是被可达性算法标记为不可用,然后进入第二次筛选,筛选条件是对象是否有必要执行finalize() ...
- Selenium+Java - 结合sikuliX操作Flash网页
前言 前天被一个Flash的轮播图,给玩坏了,无法操作,后来请教了下crazy总拿到思路,今天实践了下,果然可以了,非常感谢! 模拟场景 打开百度地图 切换城市到北京 使用测距工具 测量 奥林匹克森林 ...
- GitHub项目:jkrasnay/sqlbuilder的使用
http://www.jianshu.com/p/7f099b8cf5f0 技术选型: 在报表查询时,通常需要做可以动态添加的条件 在老项目中使用的是一种Tcondition的对象分装sql impo ...
- Web很脆弱,SQL注入要了解
SQL注入 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 通过一下的例子更形象的了解SQL注入: 有一个Login ...