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

==>>点击查看本系列文章目录

 

ORM框架(持久化流程)

session是事务 (transaction) 的工厂,处理session后,所有更改将自动刷新到数据库中。或者,如果要处理何时将更改刷新到数据库,即transaction将在session处理完后异步提交。session也可以取消事务

(四)数据持久化(基于YesSql)_第1张图片

新建两个项目,Data 与 Data.Abstractions, 其中 Data.Abstractions 为对外抽象接口(面向对象设计原则),并用Nuget添加程序包。

(四)数据持久化(基于YesSql)_第2张图片

 

(四)数据持久化(基于YesSql)_第3张图片

 

 

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 GetFeatures();
        IEnumerable GetFeatures(string[] featureIdsToLoad);
        IEnumerable GetFeatureDependencies(string featureId);
        IEnumerable 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

  

/// 
    /// 数据库迁移管理
    /// 
    public interface IDataMigrationManager
    {
        /// 
        ///返回具有至少一个数据迁移类的特性,并调用相应的升级方法
        /// 
        Task> GetFeaturesThatNeedUpdateAsync();

        /// 
        /// 运行所有需要更新的迁移。
        /// 
        Task UpdateAllFeaturesAsync();

        /// 
        /// 将数据库更新为指定功能的最新版本
        /// 
        Task UpdateAsync(string feature);

        /// 
        /// 将数据库更新为指定功能的最新版本
        /// 
        Task UpdateAsync(IEnumerable features);

        /// 
        /// 执行脚本删除与该特性相关的任何信息
        /// 
        /// 
        Task Uninstall(string feature);
    }

  

public interface IDbConnectionAccessor
    {
        /// 
        /// 创建数据库连接
        /// 
        /// 
        DbConnection CreateConnection();
    }

  

/// 
    /// 数据库迁移工具,封装YesSql功能,直接修改数据库结构
    /// 
    public interface ISchemaBuilder
    {
        YesSql.Sql.ISchemaBuilder SchemaBuilder { get; set; }
    }

  

 

 

public static class DataAccess
    {
        public static IApplicationBuilder UseDataAccess(this IApplicationBuilder app)
        {
            return app.UseMiddleware();
        }


        /// 
        /// 添加数据库
        /// 
        /// 
        /// 数据库类型,支持:SqlConnection,Sqlite,MySql,Postgres
        /// Sqlite为yessql.db文件所在路径,其他数据库为连接字符串
        /// 表名前缀
        /// 
        public static IServiceCollection AddDataAccess(this IServiceCollection services, string databaseType, string connectionString, string tablePrefix = null)
        {
            services.AddScoped();

            // 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(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();

                store.RegisterIndexes(indexes);

                return store;
            });

            services.AddScoped(sp =>
            {
                var store = sp.GetService();

                if (store == null)
                {
                    return null;
                }

                var session = store.CreateSession();

                var scopedServices = sp.GetServices();

                session.RegisterIndexes(scopedServices.ToArray());

                var httpContext = sp.GetRequiredService()?.HttpContext;

                if (httpContext != null)
                {
                    httpContext.Items[typeof(YesSql.ISession)] = session;
                }

                return session;
            });

            services.AddTransient();

            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))