From 9f2ffdce77ef0717e45d3df01b796e77d1599699 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 22:36:39 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Generator=20Sq?= =?UTF-8?q?lite=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=94=9F=E6=88=90=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20Sqlite?= =?UTF-8?q?=20DbFirst=20=E5=AE=9E=E7=8E=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 10 +- .../FreeSql.Generator.csproj | 5 +- Extensions/FreeSql.Generator/RazorModel.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - .../FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs | 25 ++ FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 359 ++++++++++++++++++ .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 3 +- 8 files changed, 398 insertions(+), 17 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs create mode 100644 Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index c8d9e46d..c32b25ca 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -102,9 +102,11 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{8},Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=数据库;Pooling=true;Maximum Pool Size=2"" -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"" + + -DB ""{10},Data Source=document.db;Attachs=xxxtb.db;"" - -DB ""{10},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" - {10} 是国产达梦数据库,需要使用 ODBC 连接 + -DB ""{11},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" + {11} 是国产达梦数据库,需要使用 ODBC 连接 -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 @@ -113,7 +115,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 - {11} + {12} ", Color.SlateGray, new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), @@ -126,6 +128,7 @@ new Colorful.Formatter("MySql", Color.Yellow), new Colorful.Formatter("SqlServer", Color.Yellow), new Colorful.Formatter("PostgreSQL", Color.Yellow), new Colorful.Formatter("Oracle", Color.Yellow), +new Colorful.Formatter("Sqlite", Color.Yellow), new Colorful.Formatter("OdbcDameng", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); @@ -165,6 +168,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "sqlserver": ArgsDbType = DataType.SqlServer; break; case "postgresql": ArgsDbType = DataType.PostgreSQL; break; case "oracle": ArgsDbType = DataType.Oracle; break; + case "sqlite": ArgsDbType = DataType.Sqlite; break; case "odbcdameng": ArgsDbType = DataType.OdbcDameng; break; default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); } diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5d8e0c49..d5aecb79 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;netcoreapp2.1 + netcoreapp3.1 true true true @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.1 + 1.3.1.5 FreeSql DbFirst 实体生成器 @@ -27,6 +27,7 @@ + diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 07e5bb6a..e2be6979 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -73,7 +73,7 @@ public class RazorModel { if (col.CsType != null) { var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); - if (dbinfo != null && dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) + if (dbinfo != null && string.Compare(dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim(), col.DbTypeTextFull, true) != 0) sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); if (col.IsPrimary) sb.Add("IsPrimary = true"); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs new file mode 100644 index 00000000..8725e453 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.sqlite.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.sqlite.DbFirst.GetTablesByDatabase(); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 985eae8b..ba3a65d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -71,7 +71,7 @@ public class g public static IFreeSql oracle => oracleLazy.Value; static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db") //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => //{ // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs new file mode 100644 index 00000000..74908fdd --- /dev/null +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -0,0 +1,359 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Sqlite +{ + class SqliteDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public SqliteDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "boolean": return DbType.Boolean; + + case "smallint": return DbType.Int16; + case "integer": return DbType.Int32; + case "bigint": return DbType.Int64; + + case "int2": return DbType.Byte; + case "unsigned": return DbType.Decimal; + case "decimal(10,0)": return DbType.Decimal; + case "decimal(21,0)": return DbType.Decimal; + + case "double": return DbType.Double; + case "float": return DbType.Single; + case "decimal(10,2)": return DbType.Decimal; + case "datetime": return DbType.DateTime; + + case "blob": return DbType.Binary; + case "nvarchar(255)": return DbType.String; + + case "character(36)": return DbType.AnsiString; + } + switch (column.DbTypeText.ToLower()) + { + case "int": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["integer"]); + return DbType.Int32; + case "tinyint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["int2"]); + return DbType.Byte; + case "mediumint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["bigint"]); + return DbType.Int64; + case "unsigned big int": + case "int8": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["bigint"]); + return DbType.Int64; + + case "numeric": + case "decimal": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["decimal(10,2)"]); + return DbType.Decimal; + + case "date": + case "smalldatetime": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["datetime"]); + return DbType.Date; + + case "real": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float"]); + return DbType.Double; + case "double precision": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["double"]); + return DbType.Double; + + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DbType.Binary; + + case "character": + case "varchar": + case "varying character": + case "nchar": + case "native character": + case "nvarchar": + case "text": + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar(255)"]); + return DbType.String; + + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar(255)"]); + return DbType.String; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static SqliteDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "boolean", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "smallint", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "integer", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "bigint", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "int2", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "unsigned", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "decimal(10,0)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "decimal(21,0)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "double", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "decimal(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "datetime", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "character(36)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + return _orm.Ado.ExecuteArray("PRAGMA database_list").Select(a => string.Concat(a[1])).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) database = GetDatabases().ToArray(); + if (database.Any() == false) return loc1; + + Action addColumn = row => + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + bool is_primary = string.Concat(row[7]) == "1"; + string comment = string.Concat(row[8]); + if (max_length == 0) max_length = -1; + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = is_primary, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + }; + + foreach (var db in database) + { + var sql = $@"select +'{db}.' || tbl_name, +'{db}', +tbl_name, +'' Comment, +'TABLE', +sql +from {db}.sqlite_master where type = 'table'"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) continue; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + + if (type == DbTableType.TABLE && table != "sqlite_sequence") + { + var dsql = string.Concat(row[5]); + var cols = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".table_info(\"{table}\")"); + foreach (var col in cols) + { + var col_name = string.Concat(col[1]); + var is_identity = false; + var dsqlIdx = dsql?.IndexOf($"\"{col_name}\" "); + if (dsqlIdx > 0) + { + var dsqlLastIdx = dsql.IndexOf('\n', dsqlIdx.Value); + if (dsqlLastIdx > 0) is_identity = dsql.Substring(dsqlIdx.Value, dsqlLastIdx - dsqlIdx.Value).Contains("AUTOINCREMENT"); + } + + var ds2item = new object[9]; + ds2item[0] = table_id; + ds2item[1] = col_name; + ds2item[2] = Regex.Replace(string.Concat(col[2]), @"\(\d+(\b*,\b*\d+)?\)", "").ToUpper(); + ds2item[4] = string.Concat(col[2]).ToUpper(); + ds2item[5] = string.Concat(col[5]) == "0" && string.Concat(col[3]) == "0" ? 1 : 0; + ds2item[6] = is_identity; + ds2item[7] = string.Concat(col[5]) == "1" ? 1 : 0; + ds2item[8] = ""; + addColumn(ds2item); + } + + var fks = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".foreign_key_list(\"{table}\")"); + if (fks != null && fks.Length > 0) + { + var fkColumns = new Dictionary>(); + foreach (var fk in fks) + { + string column = string.Concat(fk[3]); + string fk_id = $"{db}.{table}.{fk[0]}"; + string ref_table_id = database.Length == 1 ? string.Concat(fk[2]) : $"{db}.{fk[2]}"; + string referenced_column = string.Concat(fk[4]); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id2 in fkColumns.Keys) + foreach (var fk in fkColumns[table_id2]) + loc2[table_id2].ForeignsDict.Add(fk.Key, fk.Value); + } + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) continue; + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + //if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 972137b6..8782b6d6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -28,7 +28,7 @@ namespace FreeSql.Sqlite public IAdo Ado { get; } public IAop Aop { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); + public IDbFirst DbFirst { get; }// => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); public SqliteProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqliteUtils(this); @@ -38,6 +38,7 @@ namespace FreeSql.Sqlite this.Aop = new AopProvider(); this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.DbFirst = new SqliteDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); if (connectionFactory != null) this.CodeFirst.IsNoneCommandParameter = true; }