(四)数据持久化(基于YesSql)

匿名 (未验证) 提交于 2019-12-02 22:06:11

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;         }     } 

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!