From b92f480cda0b8369b793eef62bb5ee7d0197de07 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Jan 2019 17:34:36 +0800 Subject: [PATCH] update --- .../PostgreSQLTemplateGeneratorTest.cs | 27 ++ FreeSql/Generator/TemplateEngin.cs | 3 +- FreeSql/Oracle/OracleDbFirst.cs | 385 ------------------ FreeSql/Oracle/OracleProvider.cs | 3 +- FreeSql/PostgreSQL/PostgreSQLDbFirst.cs | 3 +- FreeSql/Sqlite/SqliteDbFirst.cs | 385 ------------------ FreeSql/Sqlite/SqliteProvider.cs | 3 +- .../rich-entity-navigation-object/Const.cs | 5 + .../Model/for-table.cs.freesql | 240 +++++++++++ .../rich-entity-navigation-object/readme.md | 94 +++++ .../Model/for-table.cs.freesql | 60 +++ .../simple-entity-navigation-object/readme.md | 94 +++++ .../simple-entity/Model/for-table.cs.freesql | 35 ++ Templates/PostgreSQL/simple-entity/readme.md | 94 +++++ readme.md | 12 + 15 files changed, 667 insertions(+), 776 deletions(-) create mode 100644 FreeSql.Tests/Generator/PostgreSQLTemplateGeneratorTest.cs delete mode 100644 FreeSql/Oracle/OracleDbFirst.cs delete mode 100644 FreeSql/Sqlite/SqliteDbFirst.cs create mode 100644 Templates/PostgreSQL/rich-entity-navigation-object/Const.cs create mode 100644 Templates/PostgreSQL/rich-entity-navigation-object/Model/for-table.cs.freesql create mode 100644 Templates/PostgreSQL/rich-entity-navigation-object/readme.md create mode 100644 Templates/PostgreSQL/simple-entity-navigation-object/Model/for-table.cs.freesql create mode 100644 Templates/PostgreSQL/simple-entity-navigation-object/readme.md create mode 100644 Templates/PostgreSQL/simple-entity/Model/for-table.cs.freesql create mode 100644 Templates/PostgreSQL/simple-entity/readme.md diff --git a/FreeSql.Tests/Generator/PostgreSQLTemplateGeneratorTest.cs b/FreeSql.Tests/Generator/PostgreSQLTemplateGeneratorTest.cs new file mode 100644 index 00000000..87facccb --- /dev/null +++ b/FreeSql.Tests/Generator/PostgreSQLTemplateGeneratorTest.cs @@ -0,0 +1,27 @@ +using FreeSql.DataAnnotations; +using FreeSql.Generator; +using System; +using Xunit; + +namespace FreeSql.Tests.Generator { + public class PostgreSQLTemplateGeneratorTest { + + [Fact] + public void BuildSimpleEntity() { + var gen = new TemplateGenerator(); + gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); + } + + [Fact] + public void BuildSimpleEntityNavigationObject () { + var gen = new TemplateGenerator(); + gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); + } + + [Fact] + public void BuildRichEntityNavigationObject() { + var gen = new TemplateGenerator(); + gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); + } + } +} diff --git a/FreeSql/Generator/TemplateEngin.cs b/FreeSql/Generator/TemplateEngin.cs index de199a8f..9d8a905b 100644 --- a/FreeSql/Generator/TemplateEngin.cs +++ b/FreeSql/Generator/TemplateEngin.cs @@ -541,7 +541,8 @@ return rTn;"); #region Complie private static ITemplateOutput Complie(string cscode, string typename) { var assemly = _compiler.Value.CompileCode(cscode); - return assemly.CreateInstance(typename) as ITemplateOutput; + var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith(typename)).FirstOrDefault(); + return Activator.CreateInstance(type) as ITemplateOutput; } static ConcurrentDictionary _compiler_objs = new ConcurrentDictionary(); static Lazy _compiler = new Lazy(() => { diff --git a/FreeSql/Oracle/OracleDbFirst.cs b/FreeSql/Oracle/OracleDbFirst.cs deleted file mode 100644 index 8966920c..00000000 --- a/FreeSql/Oracle/OracleDbFirst.cs +++ /dev/null @@ -1,385 +0,0 @@ -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using MySql.Data.MySqlClient; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text.RegularExpressions; - -namespace FreeSql.Oracle { - class OracleDbFirst : IDbFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public OracleDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } - - public int GetDbType(DbColumnInfo column) => (int)GetMySqlDbType(column); - MySqlDbType GetMySqlDbType(DbColumnInfo column) { - var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned"); - switch (column.DbTypeText.ToLower()) { - case "bit": return MySqlDbType.Bit; - - case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte; - case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16; - case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24; - case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32; - case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64; - - case "real": - case "double": return MySqlDbType.Double; - case "float": return MySqlDbType.Float; - case "numeric": - case "decimal": return MySqlDbType.Decimal; - - case "year": return MySqlDbType.Year; - case "time": return MySqlDbType.Time; - case "date": return MySqlDbType.Date; - case "timestamp": return MySqlDbType.Timestamp; - case "datetime": return MySqlDbType.DateTime; - - case "tinyblob": return MySqlDbType.TinyBlob; - case "blob": return MySqlDbType.Blob; - case "mediumblob": return MySqlDbType.MediumBlob; - case "longblob": return MySqlDbType.LongBlob; - - case "binary": return MySqlDbType.Binary; - case "varbinary": return MySqlDbType.VarBinary; - - case "tinytext": return MySqlDbType.TinyText; - case "text": return MySqlDbType.Text; - case "mediumtext": return MySqlDbType.MediumText; - case "longtext": return MySqlDbType.LongText; - - case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String; - case "varchar": return MySqlDbType.VarChar; - - case "set": return MySqlDbType.Set; - case "enum": return MySqlDbType.Enum; - - case "point": return MySqlDbType.Geometry; - case "linestring": return MySqlDbType.Geometry; - case "polygon": return MySqlDbType.Geometry; - case "geometry": return MySqlDbType.Geometry; - case "multipoint": return MySqlDbType.Geometry; - case "multilinestring": return MySqlDbType.Geometry; - case "multipolygon": return MySqlDbType.Geometry; - case "geometrycollection": return MySqlDbType.Geometry; - default: return MySqlDbType.String; - } - } - - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - - { (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - - { (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, - - { (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - - { (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - - { (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - - { (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - - { (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - - { (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - - { (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(bool), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(bool), typeof(Enum), "{0}", "GetInt64") }, - - { (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, - }; - - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - - public List GetDatabases() { - var sql = @" select username from sys.dba_users"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } - - public List GetTablesByDatabase(params string[] database) { - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); - - if (database == null || database.Any() == false) return loc1; - var databaseIn = string.Join(",", database.Select(a => "{0}".FormatMySql(a))); - var sql = string.Format(@" -select -concat(a.table_schema, '.', a.table_name) 'id', -a.table_schema 'schema', -a.table_name 'table', -a.table_type 'type' -from information_schema.tables a -where a.table_schema in ({0})", databaseIn); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var loc6 = new List(); - var loc66 = 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 type = string.Concat(row[3]) == "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, Type = type }); - loc3.Add(table_id, new Dictionary()); - switch (type) { - case DbTableType.TABLE: - case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); - break; - case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); - break; - } - } - if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; - - sql = string.Format(@" -select -concat(a.table_schema, '.', a.table_name), -a.column_name, -a.data_type, -ifnull(a.character_maximum_length, 0) 'len', -a.column_type, -case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', -case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', -a.column_comment 'comment' -from information_schema.columns a -where a.table_schema in ({1}) and a.table_name in ({0}) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - foreach (var row in ds) { - 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"; - string comment = string.Concat(row[7]); - if (max_length == 0) max_length = -1; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - loc3[table_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - 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]); - } - - sql = string.Format(@" -select -concat(a.constraint_schema, '.', a.table_name) 'table_id', -a.column_name, -concat(a.constraint_schema, '/', a.table_name, '/', a.constraint_name) 'index_id', -1 'IsUnique', -case when constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', -0 'IsClustered', -0 'IsDesc' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string index_id = string.Concat(row[2]); - bool is_unique = string.Concat(row[3]) == "1"; - bool is_primary_key = string.Concat(row[4]) == "1"; - bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique) { - if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (string table_id in indexColumns.Keys) { - foreach (var columns in indexColumns[table_id].Values) - loc2[table_id].Indexes.Add(columns); - } - foreach (string table_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[table_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].Uniques.Add(columns); - } - } - - sql = string.Format(@" -select -concat(a.constraint_schema, '.', a.table_name) 'table_id', -a.column_name, -concat(a.constraint_schema, '/', a.constraint_name) 'FKId', -concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', -1 'IsForeignKey', -a.referenced_column_name 'ref_column' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var fkColumns = new Dictionary>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - 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_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); - - 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.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - 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.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; - 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; - }); - foreach(var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach(var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } - - loc2.Clear(); - loc3.Clear(); - return loc1; - } - - public List GetEnumsByDatabase(params string[] database) { - return new List(); - } - } -} \ No newline at end of file diff --git a/FreeSql/Oracle/OracleProvider.cs b/FreeSql/Oracle/OracleProvider.cs index 7e3c8bd8..669fb1cd 100644 --- a/FreeSql/Oracle/OracleProvider.cs +++ b/FreeSql/Oracle/OracleProvider.cs @@ -25,7 +25,7 @@ namespace FreeSql.Oracle { public IAdo Ado { get; } public ICache Cache { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } + public IDbFirst DbFirst { get { throw new NotImplementedException(); } } public OracleProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Oracle"); @@ -35,7 +35,6 @@ namespace FreeSql.Oracle { this.Cache = new CacheProvider(cache, log); this.Ado = new OracleAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); - this.DbFirst = new OracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.InternalCommonUtils.CodeFirst = this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } diff --git a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs index dfaf9e4b..9343ea57 100644 --- a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs +++ b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs @@ -270,6 +270,7 @@ and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geo sql = $@" select ns.nspname || '.' || c.relname as id, +a.attname, t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, @@ -289,7 +290,7 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname || '.' || c.relname in ({loc88})"; +where ns.nspname || '.' || c.relname in ({loc8})"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/FreeSql/Sqlite/SqliteDbFirst.cs b/FreeSql/Sqlite/SqliteDbFirst.cs deleted file mode 100644 index 7bac4c6b..00000000 --- a/FreeSql/Sqlite/SqliteDbFirst.cs +++ /dev/null @@ -1,385 +0,0 @@ -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using MySql.Data.MySqlClient; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -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)GetMySqlDbType(column); - MySqlDbType GetMySqlDbType(DbColumnInfo column) { - var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned"); - switch (column.DbTypeText.ToLower()) { - case "bit": return MySqlDbType.Bit; - - case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte; - case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16; - case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24; - case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32; - case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64; - - case "real": - case "double": return MySqlDbType.Double; - case "float": return MySqlDbType.Float; - case "numeric": - case "decimal": return MySqlDbType.Decimal; - - case "year": return MySqlDbType.Year; - case "time": return MySqlDbType.Time; - case "date": return MySqlDbType.Date; - case "timestamp": return MySqlDbType.Timestamp; - case "datetime": return MySqlDbType.DateTime; - - case "tinyblob": return MySqlDbType.TinyBlob; - case "blob": return MySqlDbType.Blob; - case "mediumblob": return MySqlDbType.MediumBlob; - case "longblob": return MySqlDbType.LongBlob; - - case "binary": return MySqlDbType.Binary; - case "varbinary": return MySqlDbType.VarBinary; - - case "tinytext": return MySqlDbType.TinyText; - case "text": return MySqlDbType.Text; - case "mediumtext": return MySqlDbType.MediumText; - case "longtext": return MySqlDbType.LongText; - - case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String; - case "varchar": return MySqlDbType.VarChar; - - case "set": return MySqlDbType.Set; - case "enum": return MySqlDbType.Enum; - - case "point": return MySqlDbType.Geometry; - case "linestring": return MySqlDbType.Geometry; - case "polygon": return MySqlDbType.Geometry; - case "geometry": return MySqlDbType.Geometry; - case "multipoint": return MySqlDbType.Geometry; - case "multilinestring": return MySqlDbType.Geometry; - case "multipolygon": return MySqlDbType.Geometry; - case "geometrycollection": return MySqlDbType.Geometry; - default: return MySqlDbType.String; - } - } - - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - - { (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - - { (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, - - { (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - - { (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - - { (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - - { (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - - { (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - - { (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - - { (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - - { (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, - }; - - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - - public List GetDatabases() { - var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } - - public List GetTablesByDatabase(params string[] database) { - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); - - if (database == null || database.Any() == false) return loc1; - var databaseIn = string.Join(",", database.Select(a => "{0}".FormatMySql(a))); - var sql = string.Format(@" -select -concat(a.table_schema, '.', a.table_name) 'id', -a.table_schema 'schema', -a.table_name 'table', -a.table_type 'type' -from information_schema.tables a -where a.table_schema in ({0})", databaseIn); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var loc6 = new List(); - var loc66 = 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 type = string.Concat(row[3]) == "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, Type = type }); - loc3.Add(table_id, new Dictionary()); - switch (type) { - case DbTableType.TABLE: - case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); - break; - case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); - break; - } - } - if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; - - sql = string.Format(@" -select -concat(a.table_schema, '.', a.table_name), -a.column_name, -a.data_type, -ifnull(a.character_maximum_length, 0) 'len', -a.column_type, -case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', -case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', -a.column_comment 'comment' -from information_schema.columns a -where a.table_schema in ({1}) and a.table_name in ({0}) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - foreach (var row in ds) { - 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"; - string comment = string.Concat(row[7]); - if (max_length == 0) max_length = -1; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - loc3[table_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - 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]); - } - - sql = string.Format(@" -select -concat(a.constraint_schema, '.', a.table_name) 'table_id', -a.column_name, -concat(a.constraint_schema, '/', a.table_name, '/', a.constraint_name) 'index_id', -1 'IsUnique', -case when constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', -0 'IsClustered', -0 'IsDesc' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string index_id = string.Concat(row[2]); - bool is_unique = string.Concat(row[3]) == "1"; - bool is_primary_key = string.Concat(row[4]) == "1"; - bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique) { - if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (string table_id in indexColumns.Keys) { - foreach (var columns in indexColumns[table_id].Values) - loc2[table_id].Indexes.Add(columns); - } - foreach (string table_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[table_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].Uniques.Add(columns); - } - } - - sql = string.Format(@" -select -concat(a.constraint_schema, '.', a.table_name) 'table_id', -a.column_name, -concat(a.constraint_schema, '/', a.constraint_name) 'FKId', -concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', -1 'IsForeignKey', -a.referenced_column_name 'ref_column' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var fkColumns = new Dictionary>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - 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_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); - - 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.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - 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.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; - 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; - }); - foreach(var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach(var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } - - loc2.Clear(); - loc3.Clear(); - return loc1; - } - - public List GetEnumsByDatabase(params string[] database) { - return new List(); - } - } -} \ No newline at end of file diff --git a/FreeSql/Sqlite/SqliteProvider.cs b/FreeSql/Sqlite/SqliteProvider.cs index 87652cbd..ddb516bd 100644 --- a/FreeSql/Sqlite/SqliteProvider.cs +++ b/FreeSql/Sqlite/SqliteProvider.cs @@ -25,7 +25,7 @@ namespace FreeSql.Sqlite { public IAdo Ado { get; } public ICache Cache { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } + public IDbFirst DbFirst { get { throw new NotImplementedException(); } } public SqliteProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Sqlite"); @@ -35,7 +35,6 @@ namespace FreeSql.Sqlite { this.Cache = new CacheProvider(cache, log); this.Ado = new SqliteAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); - this.DbFirst = new SqliteDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.InternalCommonUtils.CodeFirst = this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } diff --git a/Templates/PostgreSQL/rich-entity-navigation-object/Const.cs b/Templates/PostgreSQL/rich-entity-navigation-object/Const.cs new file mode 100644 index 00000000..783e7d9e --- /dev/null +++ b/Templates/PostgreSQL/rich-entity-navigation-object/Const.cs @@ -0,0 +1,5 @@ +public static class Const { + public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") + .Build(); +} diff --git a/Templates/PostgreSQL/rich-entity-navigation-object/Model/for-table.cs.freesql b/Templates/PostgreSQL/rich-entity-navigation-object/Model/for-table.cs.freesql new file mode 100644 index 00000000..7a454552 --- /dev/null +++ b/Templates/PostgreSQL/rich-entity-navigation-object/Model/for-table.cs.freesql @@ -0,0 +1,240 @@ +{%if (table.Type == DbTableType.StoreProcedure) { + print("return;"); + return rTn; + } + %}using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql; +using FreeSql.DataAnnotations; +{% +var dbf = dbfirst as FreeSql.IDbFirst; +var cols = (table.Columns as List); +var pks = (table.Primarys as List); +var fks = (table.Foreigns as List); + +Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); +Func GetCsType = cola3 => { + return dbf.GetCsType(cola3); +}; +Func GetFkObjectName = fkx => { + var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); + if (eqfks.Count() == 1) return "Obj_" + fkx.ReferencedTable.Name; + var fkretname = fkx.Columns[0].Name; + if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_'); + if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_'); + if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_'); + return "Obj_" + fkx.ReferencedTable.Name + (string.IsNullOrEmpty(fkretname) ? "" : ("_" + fkretname)); +}; + +%} +namespace test.Model { + + [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] + public partial class {#UString(table.Name)} {{for col,index in table.Columns}{% + var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any()); + %}{if findfks.Any() == false} + {if string.IsNullOrEmpty(col.Coment) == false}/// + /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} + /// {/if} + [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] + public {#GetCsType(col)} {#UString(col.Name)} { get; set; } + {else} + private {#GetCsType(col)} _{#UString(col.Name)}; + {if string.IsNullOrEmpty(col.Coment) == false}/// + /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} + /// {/if} + [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] + public {#GetCsType(col)} {#UString(col.Name)} { get => _{#UString(col.Name)}; set { + if (_{#UString(col.Name)} == value) return; + _{#UString(col.Name)} = value;{for fkcok2 in findfks} + {#GetFkObjectName(fkcok2)} = null;{/for} + } } + {/if}{/for}{for fk in fks} + public {#UString(fk.ReferencedTable.Name)} {#GetFkObjectName(fk)} { get; set; } + {/for} + internal static IFreeSql freesql => Const.sqlserver; + public static ISelect<{#UString(table.Name)}> Select => freesql.Select<{#UString(table.Name)}>(); +{if (table.Uniques.Count > 0)} + public static int ItemCacheTimeout = 180;{for uk001 in table.Uniques}{% + + string parms = string.Empty; + string parmsByWhereLambda = string.Empty; + string parmsBy = "By"; + string parmsNodeTypeUpdateCacheRemove = string.Empty; + foreach (var uk001col in uk001) { + string getcstype = GetCsType(uk001col); + parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", "; + parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && "; + parmsBy += UString(uk001col.Name) + "And"; + parmsNodeTypeUpdateCacheRemove += "item." + UString(uk001col.Name) + ", \"_,_\", "; + } + parms = parms.Substring(0, parms.Length - 2); + parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4); + parmsBy = parmsBy.Substring(0, parmsBy.Length - 3); + parmsNodeTypeUpdateCacheRemove = parmsNodeTypeUpdateCacheRemove.Substring(0, parmsNodeTypeUpdateCacheRemove.Length - 9); + %} + public static {#UString(table.Name)} GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) => Select.Where(a => {#parmsByWhereLambda}).Caching(ItemCacheTimeout, string.Concat("test:{#table.Name}{#uk001[0].IsPrimary ? string.Empty : parmsBy}:", {#parmsNodeTypeUpdateCacheRemove.Replace("item.", "")})).ToOne();{/for} +{for uk001 in table.Uniques}{% + + string parms = string.Empty; + string parmsByWhereLambda = string.Empty; + string parmsNewItem = string.Empty; + string parmsBy = "By"; + string parmsNoneType = string.Empty; + foreach (var uk001col in uk001) { + string getcstype = GetCsType(uk001col); + parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", "; + parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && "; + parmsNewItem += UString(uk001col.Name) + " = " + UString(uk001col.Name) + ", "; + parmsBy += UString(uk001col.Name) + "And"; + parmsNoneType += UString(uk001col.Name) + ", "; + } + parms = parms.Substring(0, parms.Length - 2); + parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4); + parmsNewItem = parmsNewItem.Substring(0, parmsNewItem.Length - 2); + parmsBy = parmsBy.Substring(0, parmsBy.Length - 3); + parmsNoneType = parmsNoneType.Substring(0, parmsNoneType.Length - 2); + %} + public static long Delete{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) { + var affrows = freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();{if table.Uniques.Count > 1} + if (ItemCacheTimeout > 0) RemoveCache(GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parmsNoneType}));{else} + if (ItemCacheTimeout > 0) RemoveCache(new {#UString(table.Name)} { {#parmsNewItem} });{/if} + return affrows; + }{/for} +{for fkcoldel in fks}{% + string parms = string.Empty; + string parmsBy = "By"; + string parmsByWhereLambda = string.Empty; + foreach( var fkcoldelcol in fkcoldel.Columns) { + string getcstype = GetCsType(fkcoldelcol); + parms += getcstype.Replace("?", "") + " " + UString(fkcoldelcol.Name) + ", "; + parmsBy += UString(fkcoldelcol.Name) + "And"; + parmsByWhereLambda += "a." + UString(fkcoldelcol.Name) + " == " + UString(fkcoldelcol.Name) + " && "; + } + parms = parms.Substring(0, parms.Length - 2); + parmsBy = parmsBy.Substring(0, parmsBy.Length - 3); + parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4); + %} + public static long DeleteBy{#parmsBy}({#parms}) { + return freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows(); //删除缓存 + } +{/for}{% string redisRemoveCode = string.Empty; %}{for uk001 in table.Uniques}{% + + string parmsBy = "By"; + string parmsNodeTypeUpdateCacheRemove = string.Empty; + foreach (var uk001col in uk001) { + parmsBy += UString(uk001col.Name) + "And"; + parmsNodeTypeUpdateCacheRemove += "item." + UString(uk001col.Name) + ", \"_,_\", "; + } + parmsBy = parmsBy.Substring(0, parmsBy.Length - 3); + parmsNodeTypeUpdateCacheRemove = parmsNodeTypeUpdateCacheRemove.Substring(0, parmsNodeTypeUpdateCacheRemove.Length - 9); + redisRemoveCode += $@" + keys[keysIdx++] = string.Concat(""test:{table.Name}{(uk001[0].IsPrimary ? string.Empty : parmsBy)}:"", {parmsNodeTypeUpdateCacheRemove});"; + %}{/for} + internal static void RemoveCache({#UString(table.Name)} item) => RemoveCache(item == null ? null : new [] { item }); + internal static void RemoveCache(IEnumerable<{#UString(table.Name)}> items) { + if (ItemCacheTimeout <= 0 || items == null || items.Any() == false) return; + var keys = new string[items.Count() * {#table.Uniques.Count}]; + var keysIdx = 0; + foreach (var item in items) {{#redisRemoveCode} + } + if (freesql.Ado.TransactionCurrentThread != null) freesql.Ado.TransactionPreRemoveCache(keys); + else freesql.Cache.Remove(keys); + } +{if (table.Columns.Count < 100)}{% + string CsParam3 = string.Empty; + string CsParamNoType3 = string.Empty; + string parms = string.Empty; + string parmsByWhereLambda = string.Empty; + string parmsNewItem = string.Empty; + string parmsBy = "By"; + string parmsNoneType = string.Empty; + var idens = 0; + var idensCol = table.Columns[0]; + foreach (var uk001col in table.Columns) { + string getcstype = GetCsType(uk001col); + parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", "; + if (uk001col.IsPrimary) + parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && "; + parmsNewItem += UString(uk001col.Name) + " = " + UString(uk001col.Name) + ", "; + parmsBy += UString(uk001col.Name) + "And"; + parmsNoneType += UString(uk001col.Name) + ", "; + if (uk001col.IsIdentity) { + idens++; + idensCol = uk001col; + } else { + if (getcstype.StartsWith("DateTime") && (uk001col.Name.ToLower() == "create_time" || uk001col.Name.ToLower() == "update_time" || uk001col.Name.ToLower() == "createtime" || uk001col.Name.ToLower() == "updatetime") || + getcstype == "bool?" && (uk001col.Name.ToLower() == "is_deleted" || uk001col.Name.ToLower() == "isdeleted")) { + + } else { + CsParam3 += getcstype + " " + UString(uk001col.Name) + ", "; + CsParamNoType3 += string.Format("\r\n {0} = {0}, ", UString(uk001col.Name)); + } + } + } + parms = parms.Substring(0, parms.Length - 2); + if (parmsByWhereLambda.Length > 0) parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4); + parmsNewItem = parmsNewItem.Substring(0, parmsNewItem.Length - 2); + parmsBy = parmsBy.Substring(0, parmsBy.Length - 3); + parmsNoneType = parmsNoneType.Substring(0, parmsNoneType.Length - 2); + if (CsParam3.Length > 0) CsParam3 = CsParam3.Substring(0, CsParam3.Length - 2); + if (CsParamNoType3.Length > 0) CsParamNoType3 = CsParamNoType3.Substring(0, CsParamNoType3.Length - 2); + %}{if idens > 0} + public static {#GetCsType(idensCol)} Insert({#UString(table.Name)} item) { + item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteIdentity(); + if (ItemCacheTimeout > 0) RemoveCache(item); + return item.{#UString(idensCol.Name)}; + }{else} + public static void Insert({#UString(table.Name)} item) { + if (ItemCacheTimeout > 0) RemoveCache(item); + freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows(); + } + public static long Insert(IEnumerable<{#UString(table.Name)}> items) { + if (ItemCacheTimeout > 0) RemoveCache(items); + return freesql.Insert<{#UString(table.Name)}>().AppendData(items).ExecuteAffrows(); + }{/if} + {if CsParamNoType3.Split('=').Length <= 5}{if idens > 0} + public static {#GetCsType(idensCol)} Insert({#CsParam3}) { + var item = new {#UString(table.Name)} {{#CsParamNoType3}}; + item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(new {#UString(table.Name)} {{#CsParamNoType3}}).ExecuteIdentity(); + if (ItemCacheTimeout > 0) RemoveCache(item); + return item.{#UString(idensCol.Name)}; + }{else} + public static {#UString(table.Name)} Insert({#CsParam3}) { + var item = new {#UString(table.Name)} {{#CsParamNoType3}}; + freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows(); + if (ItemCacheTimeout > 0) RemoveCache(item); + return item; + }{/if}{/if} + public static long Update({#UString(table.Name)} item) { + if (ItemCacheTimeout > 0) RemoveCache(item); + return freesql.Update<{#UString(table.Name)}>().SetSource(item).ExecuteAffrows(); + } + public static long Update(IEnumerable<{#UString(table.Name)}> items) { + if (ItemCacheTimeout > 0) RemoveCache(items); + return freesql.Update<{#UString(table.Name)}>().SetSource(items).ExecuteAffrows(); + } + /// + /// 指定字段更新 + /// + public IUpdate<{#UString(table.Name)}> UpdateDiy => freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}); + /// + /// {if pks.Count > 0}保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert{else}添加{/if} + /// + public void Save() {{if pks.Count > 0} + if ({#string.Join(" && ", pks.Select(pkssa => "this." + UString(pkssa.Name) + " != default(" + GetCsType(pkssa) + ")"))}) { + var affrows = freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows(); + if (affrows > 0) return; + }{/if} + {if idens > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else} + freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if} + } +{/if}{/if} + } +} \ No newline at end of file diff --git a/Templates/PostgreSQL/rich-entity-navigation-object/readme.md b/Templates/PostgreSQL/rich-entity-navigation-object/readme.md new file mode 100644 index 00000000..c95c10a5 --- /dev/null +++ b/Templates/PostgreSQL/rich-entity-navigation-object/readme.md @@ -0,0 +1,94 @@ +# 生成器 + +生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: + +| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | +| ------------- | - | - |- | - |- | - | +| simple-entity | √ | X | X | √ | X | X | +| simple-entity-navigation-object | √ | √ | X | √ | X | X | +| rich-entity-navigation-object | √ | √ | √ | X | √ | X | + +模板在项目目录:/Templates/MySql + +> 更多模板逐步开发中。。。 + +```csharp +//定义 mysql FreeSql +var mysql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") + .Build(); + +//创建模板生成类现实 +var gen = new FreeSql.Generator.TemplateGenerator(); +gen.Build(mysql.DbFirst, + @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) + @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 + "cccddd" //数据库 +); +``` + +## 模板语法 + +```html + + +{#title} + + + + +{#表达式} +{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 + + +{include ../header.html} +
+

aaa

+

bbb {#i}

+

ccc {#i}

+
+ + +{module module_name1 parms1, 2, 3...} +{/module} +{module module_name2 parms1, 2, 3...} +{/module} + + +{import ../module.html as myname} +{#myname.module_name(parms1, 2, 3...)} + + +{extends ../inc/layout.html} +{block body}{/block} + + +{% +for (var a = 0; a < 100; a++) + print(a); +%} + + +{if i === 50} +{elseif i > 60} +{else} +{/if} + + +{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} + +{for item,index in items} 可选参数称 index + 可自定义名 {for item2, index99 in 数组表达式} + +{for key,item,index on json} 可选参数 item, index, + 可自定义名 {for key2, item2, index99 in 对象表达式} +{/for} + + +{miss} +此块内容不被bmw.js解析 +{/miss} + + + +``` \ No newline at end of file diff --git a/Templates/PostgreSQL/simple-entity-navigation-object/Model/for-table.cs.freesql b/Templates/PostgreSQL/simple-entity-navigation-object/Model/for-table.cs.freesql new file mode 100644 index 00000000..f6a3ff87 --- /dev/null +++ b/Templates/PostgreSQL/simple-entity-navigation-object/Model/for-table.cs.freesql @@ -0,0 +1,60 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +using System.Net; +using Newtonsoft.Json.Linq; +using System.Net.NetworkInformation; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +{% +var dbf = dbfirst as FreeSql.IDbFirst; +var cols = (table.Columns as List); +var pks = (table.Primarys as List); +var fks = (table.Foreigns as List); + +Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); +Func GetCsType = cola3 => { + return dbf.GetCsType(cola3); +}; +Func GetFkObjectName = fkx => { + var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); + if (eqfks.Count() == 1) return "Obj_" + fkx.ReferencedTable.Name; + var fkretname = fkx.Columns[0].Name; + if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_'); + if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_'); + if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_'); + return "Obj_" + fkx.ReferencedTable.Name + (string.IsNullOrEmpty(fkretname) ? "" : ("_" + fkretname)); +}; +%} +namespace test.Model { + + [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] + public partial class {#UString(table.Name)} {{for col,index in table.Columns}{% + var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any()); + %}{if findfks.Any() == false} + {if string.IsNullOrEmpty(col.Coment) == false}/// + /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} + /// {/if} + [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] + public {#GetCsType(col)} {#UString(col.Name)} { get; set; } + {else} + private {#GetCsType(col)} _{#UString(col.Name)}; + {if string.IsNullOrEmpty(col.Coment) == false}/// + /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} + /// {/if} + [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] + public {#GetCsType(col)} {#UString(col.Name)} { get => _{#UString(col.Name)}; set { + if (_{#UString(col.Name)} == value) return; + _{#UString(col.Name)} = value;{for fkcok2 in findfks} + {#GetFkObjectName(fkcok2)} = null;{/for} + } } + {/if}{/for}{for fk in fks} + public {#UString(fk.ReferencedTable.Name)} {#GetFkObjectName(fk)} { get; set; } + {/for} + } +} \ No newline at end of file diff --git a/Templates/PostgreSQL/simple-entity-navigation-object/readme.md b/Templates/PostgreSQL/simple-entity-navigation-object/readme.md new file mode 100644 index 00000000..c95c10a5 --- /dev/null +++ b/Templates/PostgreSQL/simple-entity-navigation-object/readme.md @@ -0,0 +1,94 @@ +# 生成器 + +生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: + +| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | +| ------------- | - | - |- | - |- | - | +| simple-entity | √ | X | X | √ | X | X | +| simple-entity-navigation-object | √ | √ | X | √ | X | X | +| rich-entity-navigation-object | √ | √ | √ | X | √ | X | + +模板在项目目录:/Templates/MySql + +> 更多模板逐步开发中。。。 + +```csharp +//定义 mysql FreeSql +var mysql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") + .Build(); + +//创建模板生成类现实 +var gen = new FreeSql.Generator.TemplateGenerator(); +gen.Build(mysql.DbFirst, + @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) + @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 + "cccddd" //数据库 +); +``` + +## 模板语法 + +```html + + +{#title} + + + + +{#表达式} +{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 + + +{include ../header.html} +
+

aaa

+

bbb {#i}

+

ccc {#i}

+
+ + +{module module_name1 parms1, 2, 3...} +{/module} +{module module_name2 parms1, 2, 3...} +{/module} + + +{import ../module.html as myname} +{#myname.module_name(parms1, 2, 3...)} + + +{extends ../inc/layout.html} +{block body}{/block} + + +{% +for (var a = 0; a < 100; a++) + print(a); +%} + + +{if i === 50} +{elseif i > 60} +{else} +{/if} + + +{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} + +{for item,index in items} 可选参数称 index + 可自定义名 {for item2, index99 in 数组表达式} + +{for key,item,index on json} 可选参数 item, index, + 可自定义名 {for key2, item2, index99 in 对象表达式} +{/for} + + +{miss} +此块内容不被bmw.js解析 +{/miss} + + + +``` \ No newline at end of file diff --git a/Templates/PostgreSQL/simple-entity/Model/for-table.cs.freesql b/Templates/PostgreSQL/simple-entity/Model/for-table.cs.freesql new file mode 100644 index 00000000..c1347d76 --- /dev/null +++ b/Templates/PostgreSQL/simple-entity/Model/for-table.cs.freesql @@ -0,0 +1,35 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +using System.Net; +using Newtonsoft.Json.Linq; +using System.Net.NetworkInformation; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +{% +var dbf = dbfirst as FreeSql.IDbFirst; +var cols = (table.Columns as List); + +Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); +Func GetCsType = cola3 => { + + return dbf.GetCsType(cola3); +}; +%} +namespace test.Model { + + [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] + public partial class {#UString(table.Name)} {{for col,index in table.Columns} + {if string.IsNullOrEmpty(col.Coment) == false}/// + /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} + /// {/if} + [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] + public {#GetCsType(col)} {#UString(col.Name)} { get; set; } + {/for} + } +} \ No newline at end of file diff --git a/Templates/PostgreSQL/simple-entity/readme.md b/Templates/PostgreSQL/simple-entity/readme.md new file mode 100644 index 00000000..c95c10a5 --- /dev/null +++ b/Templates/PostgreSQL/simple-entity/readme.md @@ -0,0 +1,94 @@ +# 生成器 + +生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: + +| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | +| ------------- | - | - |- | - |- | - | +| simple-entity | √ | X | X | √ | X | X | +| simple-entity-navigation-object | √ | √ | X | √ | X | X | +| rich-entity-navigation-object | √ | √ | √ | X | √ | X | + +模板在项目目录:/Templates/MySql + +> 更多模板逐步开发中。。。 + +```csharp +//定义 mysql FreeSql +var mysql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") + .Build(); + +//创建模板生成类现实 +var gen = new FreeSql.Generator.TemplateGenerator(); +gen.Build(mysql.DbFirst, + @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) + @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 + "cccddd" //数据库 +); +``` + +## 模板语法 + +```html + + +{#title} + + + + +{#表达式} +{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 + + +{include ../header.html} +
+

aaa

+

bbb {#i}

+

ccc {#i}

+
+ + +{module module_name1 parms1, 2, 3...} +{/module} +{module module_name2 parms1, 2, 3...} +{/module} + + +{import ../module.html as myname} +{#myname.module_name(parms1, 2, 3...)} + + +{extends ../inc/layout.html} +{block body}{/block} + + +{% +for (var a = 0; a < 100; a++) + print(a); +%} + + +{if i === 50} +{elseif i > 60} +{else} +{/if} + + +{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} + +{for item,index in items} 可选参数称 index + 可自定义名 {for item2, index99 in 数组表达式} + +{for key,item,index on json} 可选参数 item, index, + 可自定义名 {for key2, item2, index99 in 对象表达式} +{/for} + + +{miss} +此块内容不被bmw.js解析 +{/miss} + + + +``` \ No newline at end of file diff --git a/readme.md b/readme.md index 1ad94fc3..171a5bc6 100644 --- a/readme.md +++ b/readme.md @@ -274,5 +274,17 @@ var t10 = fsql.Update().SetRaw("Title = {0}", "新标题").Where("Id = {0 # Part5 表达式函数 详情查看:[《Expression 表达式函数》](Docs/expression.md) +# Part6 事务 + +```csharp +fsql.Transaction(() => { + //code +}); +``` + +没异常就提交,有异常会回滚。 + +代码体内只可以使用同步方法,因为事务对象挂靠在线程关联上,使用异步方法会切换线程。 + ## 贡献者名单