diff --git "a/.Net6\347\211\210\346\234\254/VOL.Builder/Services/Core/Partial/Sys_TableInfoService.cs" "b/.Net6\347\211\210\346\234\254/VOL.Builder/Services/Core/Partial/Sys_TableInfoService.cs" index cfde8f0c6d0ab3f4f4a23481474b2cbfd9e18f8c..1e0b61b92770b487472a5869103a349d70e62fef 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Builder/Services/Core/Partial/Sys_TableInfoService.cs" +++ "b/.Net6\347\211\210\346\234\254/VOL.Builder/Services/Core/Partial/Sys_TableInfoService.cs" @@ -301,7 +301,16 @@ DISTINCT sql = GetSqlServerModelInfo(); break; } - List tableColumnInfoList = repository.DapperContext.QueryList(sql, new { tableName }); + bool issqlite = DBType.Name == DbCurrentType.sqlite.ToString(); + List tableColumnInfoList; + if (issqlite) + { + tableColumnInfoList = sysTableInfo.TableColumns.Select(e => new TableColumnInfo() { + ColumnType = e.ColumnType, ColumnName = e.ColumnName, + }).ToList(); + + }else + tableColumnInfoList = repository.DapperContext.QueryList(sql, new { tableName }); List list = sysTableInfo.TableColumns; string msg = CreateEntityModel(list, sysTableInfo, tableColumnInfoList, 1); if (msg != "") @@ -369,6 +378,10 @@ DISTINCT { sql = GetPgSqlStructure(tableName); } + else if (DBType.Name.ToLower() == DbCurrentType.sqlite.ToString().ToLower()) + { + sql = GetSqliteStructure(tableName); + } else { sql = GetSqlServerStructure(tableName); @@ -376,6 +389,11 @@ DISTINCT return sql; } + private string GetSqliteStructure(string tableName) + { + throw new NotImplementedException(); + } + /// /// 将表结构重新同步到代码生成配置 /// @@ -1262,6 +1280,7 @@ DISTINCT if (tableId > 0) return tableId; bool isMySql = DBType.Name == DbCurrentType.MySql.ToString(); + bool issqlite = DBType.Name == DbCurrentType.sqlite.ToString(); Sys_TableInfo tableInfo = new Sys_TableInfo() { ParentId = parentId, @@ -1272,7 +1291,52 @@ DISTINCT FolderName = foldername, Enable = 1 }; - List columns = repository.DapperContext + List columns; + if (issqlite) + { + + columns = new List(); + var sqlitetable_info = DBServerProvider.SqlDapper.QueryDynamicList($"pragma table_info([{tableName}])", new { }); + foreach (var item in sqlitetable_info) + { + string sqliteType = item.type.ToString(); + string cType = "string"; + int cLength = 0; + if (sqliteType.ToLower().Contains("text")) + { + cType = "string"; + cLength= sqliteType.ToLower().Replace("text(","").Replace(")","").ToInt(); + } + else if (sqliteType.ToLower().Contains("integer")) + { + cType = "int"; + + } + else if (sqliteType.ToLower().Contains("real")) + { + cType = "double"; + } + var column = new Sys_TableColumn() + { + TableName = tableName, + ColumnName = item.name, + ColumnCnName = "", + ColumnType = cType, + Maxlength = cLength, + IsKey =int.Parse(item.pk.ToString()), + IsDisplay = 1, + IsColumnData = 1, + ColumnWidth = 150, + OrderNo = 0, + IsReadDataset = int.Parse(item.pk.ToString()), + IsNull = item.notnull == 1 ? 0 : 1, + }; + columns.Add(column); + } + + } + else + columns = repository.DapperContext .QueryList(GetCurrentSql(tableName), new { tableName }); int orderNo = (columns.Count + 10) * 50; diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/DBManager/DBServerProvider.cs" "b/.Net6\347\211\210\346\234\254/VOL.Core/DBManager/DBServerProvider.cs" index 704075ce10b04fc699834a5c97934177f16bf2b4..6468c6e1661b9fa9ef0d477286c4abfdeecc26bc 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Core/DBManager/DBServerProvider.cs" +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/DBManager/DBServerProvider.cs" @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; using MySqlConnector; using Npgsql; using System; @@ -73,6 +74,10 @@ namespace VOL.Core.DBManager { return new NpgsqlConnection(connString); } + if (DBType.Name == DbCurrentType.sqlite.ToString()) + { + return new SqliteConnection(connString); + } return new SqlConnection(connString); } @@ -98,6 +103,12 @@ namespace VOL.Core.DBManager { return new NpgsqlConnection(connString); } + + if (dbCurrentType == DbCurrentType.sqlite) + { + return new SqliteConnection(connString); + } + return new SqlConnection(connString); } diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/Dapper/SqlDapper.cs" "b/.Net6\347\211\210\346\234\254/VOL.Core/Dapper/SqlDapper.cs" index b87f9cc5e6fc06aaaf59d9e7264d601571beace2..ecfffa875ad3dac69bf0afddfea9cf2651e4b7e8 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Core/Dapper/SqlDapper.cs" +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/Dapper/SqlDapper.cs" @@ -1,5 +1,6 @@  using Dapper; +using Microsoft.Data.Sqlite; using MySqlConnector; using System; using System.Collections.Generic; @@ -754,9 +755,45 @@ namespace VOL.Core.Dapper PGSqlBulkInsert(table, tableName); return table.Rows.Count; } + if (DBType.Name == "sqlite") + { + sqliteBulkInsert(table, tableName); + return table.Rows.Count; + } return MSSqlBulkInsert(table, tableName, sqlBulkCopyOptions ?? SqlBulkCopyOptions.KeepIdentity); } + private void sqliteBulkInsert(DataTable table, string tableName) + { + //待实现 + using (var Connection = new SqliteConnection(_connectionString)) + { + if (Connection.State != ConnectionState.Open) + Connection.Open(); + SQLiteBulkInsert sbi = new SQLiteBulkInsert(Connection, tableName); + for (int i = 0; i < table.Columns.Count; i++) + { + DbType dbType = DbType.String; + if(table.Columns[i].DataType==typeof(string)) + { + dbType = DbType.String; + }else if (table.Columns[i].DataType == typeof(int)) + { + dbType = DbType.Int32; + } + else if (table.Columns[i].DataType == typeof(double)) + { + dbType = DbType.Double; + } + sbi.AddParameter(table.Columns[i].ColumnName, dbType); + } + for (int x = 0; x ///大批量数据插入,返回成功插入行数 //// diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/EFDbContext/VOLContext.cs" "b/.Net6\347\211\210\346\234\254/VOL.Core/EFDbContext/VOLContext.cs" index 80270e8366a2a523681f84ff1b1824e3b65f0dc2..39abe586af96ef2509da321924e41bddacf53046 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Core/EFDbContext/VOLContext.cs" +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/EFDbContext/VOLContext.cs" @@ -80,7 +80,10 @@ namespace VOL.Core.EFDbContext { optionsBuilder.UseNpgsql(connectionString); } - else + else if(Const.DBType.Name == Enums.DbCurrentType.sqlite.ToString()) + { + optionsBuilder.UseSqlite(connectionString); + }else { optionsBuilder.UseSqlServer(connectionString); } diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/Enums/DbCurrentType.cs" "b/.Net6\347\211\210\346\234\254/VOL.Core/Enums/DbCurrentType.cs" index a703fbaa0638d6a3073bb1b6fdf45e9b3c07fea8..e4b4a010e20bf8f29305dda826548255d447d008 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Core/Enums/DbCurrentType.cs" +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/Enums/DbCurrentType.cs" @@ -9,6 +9,7 @@ namespace VOL.Core.Enums Default = 0, MySql = 1, MsSql = 2,//2020.08.08修改sqlserver拼写 - PgSql = 3 + PgSql = 3, + sqlite=4, } } diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/Utilities/SQLiteBulkInsert.cs" "b/.Net6\347\211\210\346\234\254/VOL.Core/Utilities/SQLiteBulkInsert.cs" new file mode 100644 index 0000000000000000000000000000000000000000..a5bacf4b636900c27bcb918a2d5a711a20a17149 --- /dev/null +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/Utilities/SQLiteBulkInsert.cs" @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Data.SQLite; +using System.Data; +using Microsoft.Data.Sqlite; + +namespace VOL.Core.Utilities +{ + public class SQLiteBulkInsert + { + private SqliteConnection m_dbCon; + private SqliteCommand m_cmd; + private SqliteTransaction m_trans; + + private Dictionary m_parameters =new Dictionary(); + + private uint m_counter = 0; + + private string m_beginInsertText; + + public SQLiteBulkInsert(SqliteConnection dbConnection, string tableName) + { + m_dbCon = dbConnection; + m_tableName = tableName; + + StringBuilder query = new StringBuilder(255); + query.Append("INSERT INTO ["); query.Append(tableName); query.Append("] ("); + m_beginInsertText = query.ToString(); + } + + private bool m_allowBulkInsert = true; + public bool AllowBulkInsert { get { return m_allowBulkInsert; } set { m_allowBulkInsert = value; } } + + public string CommandText + { + get + { + if (m_parameters.Count < 1) + throw new SqliteException("You must add at least one parameter.",-1); + + StringBuilder sb = new StringBuilder(255); + sb.Append(m_beginInsertText); + + foreach (string param in m_parameters.Keys) + { + sb.Append('['); + sb.Append(param); + sb.Append(']'); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2); + + sb.Append(") VALUES ("); + + foreach (string param in m_parameters.Keys) + { + sb.Append(m_paramDelim); + sb.Append(param); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2); + + sb.Append(")"); + + return sb.ToString(); + } + } + + private uint m_commitMax = 10000; + public uint CommitMax { get { return m_commitMax; } set { m_commitMax = value; } } + + private string m_tableName; + public string TableName { get { return m_tableName; } } + + private string m_paramDelim = ":"; + public string ParamDelimiter { get { return m_paramDelim; } } + + public void AddParameter(string name, DbType dbType) + { + SqliteParameter param = new SqliteParameter(m_paramDelim + name, dbType); + m_parameters.Add(name, param); + } + + public void Flush() + { + try + { + if (m_trans != null) + m_trans.Commit(); + } + catch (Exception ex) { throw new Exception("Could not commit transaction. See InnerException for more details", ex); } + finally + { + if (m_trans != null) + m_trans.Dispose(); + + m_trans = null; + m_counter = 0; + } + } + + public void Insert(object[] paramValues) + { + if (paramValues.Length != m_parameters.Count) + throw new Exception("The values array count must be equal to the count of the number of parameters."); + + m_counter++; + + if (m_counter == 1) + { + if (m_allowBulkInsert) + m_trans = m_dbCon.BeginTransaction(); + + m_cmd = m_dbCon.CreateCommand(); + foreach (SqliteParameter par in m_parameters.Values) + m_cmd.Parameters.Add(par); + + m_cmd.CommandText = this.CommandText; + } + + int i = 0; + foreach (SqliteParameter par in m_parameters.Values) + { + par.Value = paramValues[i]; + i++; + } + + m_cmd.ExecuteNonQuery(); + + if (m_counter == m_commitMax) + { + try + { + if (m_trans != null) + m_trans.Commit(); + } + catch (Exception ex) { } + finally + { + if (m_trans != null) + { + m_trans.Dispose(); + m_trans = null; + } + + m_counter = 0; + } + } + } + } +} diff --git "a/.Net6\347\211\210\346\234\254/VOL.Core/VOL.Core.csproj" "b/.Net6\347\211\210\346\234\254/VOL.Core/VOL.Core.csproj" index d43754950f6256c1f3a141e16e7f1e995d88c7e7..7645e6eeac962cd52ade5ecb3a685bb752ef6586 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.Core/VOL.Core.csproj" +++ "b/.Net6\347\211\210\346\234\254/VOL.Core/VOL.Core.csproj" @@ -47,6 +47,7 @@ + diff --git "a/.Net6\347\211\210\346\234\254/VOL.WebApi/appsettings.json" "b/.Net6\347\211\210\346\234\254/VOL.WebApi/appsettings.json" index 5a761a681156a95c34a129cc871adbc7124a962d..545ae93696ebf0d5b649a24b1582b9f454b3e045 100644 --- "a/.Net6\347\211\210\346\234\254/VOL.WebApi/appsettings.json" +++ "b/.Net6\347\211\210\346\234\254/VOL.WebApi/appsettings.json" @@ -14,10 +14,11 @@ "AppUrls": { }, "Connection": { - "DBType": "MsSql", //MySql/MsSql/PgSql //数据库类型,如果使用的是sqlserver此处应设置为MsSql + "DBType": "sqlite", //MySql/MsSql/PgSql/sqlite //数据库类型,如果使用的是sqlserver此处应设置为MsSql //sqlserver连接字符串 - "DbConnectionString": "Data Source=JXX2835\\SQLEXPRESS;Initial Catalog=netcoredev;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=500;", - + //"DbConnectionString": "Data Source=JXX2835\\SQLEXPRESS;Initial Catalog=netcoredev;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=500;", + //sqlite + "DbConnectionString": "Data Source=../../DB/sqlite/vol.db", //mysql连接字符串(升级EFCore3.1到时已将mysql连接字符串修改,2019-12-20) // "DbConnectionString": " Data Source=127.0.0.1;Database=netcoredev;AllowLoadLocalInfile=true;User ID=root;Password=123456;allowPublicKeyRetrieval=true;pooling=true;CharSet=utf8;port=3306;sslmode=none;", diff --git a/DB/sqlite/vol.db b/DB/sqlite/vol.db new file mode 100644 index 0000000000000000000000000000000000000000..1bcaa011c84bd332111cd71904d24edbf3fc5bc1 Binary files /dev/null and b/DB/sqlite/vol.db differ diff --git a/README.md b/README.md index 16a5b7324226ce22aeec50393311cd60cc26ff0d..3083efa34d39b805e8b128b4345d9dfc4cfbbb23 100644 --- a/README.md +++ b/README.md @@ -38,73 +38,73 @@ ## App/H5开发 - http://v2.volcore.xyz/app/guide ## 框架移动端(uniapp)已发布,同样全自动生成代码 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/qrcode.png) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/m001.png) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/m002.png) +![Home](/imgs/qrcode.png) +![Home](/imgs/m001.png) +![Home](/imgs/m002.png) ## 框架已支持Vue3版本 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/v3.png) +![Home](/imgs/v3.png) ## 框架已增加低代码设计器 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/fd01.png) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/fd02.png) +![Home](/imgs/fd01.png) +![Home](/imgs/fd02.png) ## 框架2.0已更新(部分新增功能截图) 增加切换皮肤功能 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/h.png) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/home_them.png) +![Home](/imgs/h.png) +![Home](/imgs/home_them.png) 增加可复用的后台请求参数校验 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/validator.png) +![Home](/imgs/validator.png) 增加树形菜单与代码生成页面使用 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/x7tree.png) +![Home](/imgs/x7tree.png) 增加文本编辑器直接发布静态页面功能 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/editor.png) +![Home](/imgs/editor.png) 一对一多从表显示(只需要少量代码就可完成成,其他都由代码生成器生成) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/m1.png) +![Home](/imgs/m1.png) 表合并显示 (只需要几行代码完成代码生成器生成的页面实现扩展) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/span.png) +![Home](/imgs/span.png) 从图上传图片 (只需要几行代码完成代码生成器生成的页面实现扩展) -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/p1.png) +![Home](/imgs/p1.png) 一对多从表(不限从表数量)扩展 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/multi.png) +![Home](/imgs/multi.png) 图表 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/charts.png) +![Home](/imgs/charts.png) ## 1、只读基础表单 整个只读的基础表单的所有前后端代码,全部由代码生成器生成,代码生成器中几乎不需要配置,并支持并后端业务代码扩展,直接生成代码后,配置菜单权限即可 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/table1.png) +![Home](/imgs/table1.png) ## 2、自动绑定下拉框数据表单 整个自动绑定下拉框数据表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,在代码生成器中只需要指定数据源编号,页面加载时会根据编号自动加载数据源并绑定 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/table2.png) +![Home](/imgs/table2.png) ## 3、启用图片支持、审核表单 整个启用图片支持、审核表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,审核功能需要在菜单配置权限、代码生成器中勾选启用图片支持 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/table3.png) +![Home](/imgs/table3.png) ## 4、高级查询 整个表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,查询字段、类型(下拉框、日期、TextArea等)、所在行与列都由代码生成器完成,不需要写任何代码 - ![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/tablesearch4.png) + ![Home](/imgs/tablesearch4.png) ## 5、主从表新建、编辑 主从表新建、编辑所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,新建、编辑从表配置、字段、类型(下拉框、日期、TextArea等)、所在行与列、字段是否只读、标签显示的长度等都由代码生成器完成,不需要写任何代码 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/editTbale2.png) +![Home](/imgs/editTbale2.png) ## 6、excel导入 excel导入整个页面都由代码生成器生成,导入的字段、字段是否必填,下载模板也由代码生成器上配置(自己根据实际需要决定是否采用此方法),导入时会验证是否为空与数据的合法性,逻辑校验自己实现扩展方法即可 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/importTable1.png) +![Home](/imgs/importTable1.png) ## 7、H5开发 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/h5.jpg) +![Home](/imgs/h5.jpg) ## 8、权限分配 目前只实现了对用户的角色的Action进行权限分配 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/auth.png) +![Home](/imgs/auth.png) ## 9、代码生成器 代码生成器提供了20多种可配置的属性,可灵活配置显示、查询、编辑、导入、导出、主从关系等功能点击看代码生成器文档 -![Home](https://github.com/cq-panda/Vue.NetCore/blob/master/imgs/coder.png) +![Home](/imgs/coder.png) 其他功能。。。。。