From a4c049fcf25e8340aa079cf523c3f49ce77f54c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jun 2020 01:46:04 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20FreeSql.Generator=20?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=95=B0=E6=8D=AE=E5=BA=93=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 2 +- .../FreeSql.Generator/RazorContentManager.cs | 28 +-- Extensions/FreeSql.Generator/RazorModel.cs | 172 +++++++++++++++++- 3 files changed, 183 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 4bc161c7..3b9f5a91 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.102 + 1.6.0 FreeSql DbFirst 实体生成器 diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index baa57000..a52036a6 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -7,17 +7,17 @@ namespace FreeSql.Generator class RazorContentManager { public static string 实体类_特性_cshtml = - #region 长内容 - @"@using FreeSql.DatabaseModel;@{ + #region 长内容 + @"using FreeSql.DatabaseModel;@{ var gen = Model as RazorModel; Func GetAttributeString = attr => { - if (string.IsNullOrEmpty(attr)) return null; + if (string.IsNullOrEmpty(attr)) return """"; return string.Concat("", "", attr.Trim('[', ']')); }; -Func GetDefaultValue = col => { - if (col.CsType == typeof(string)) return "" = string.Empty;""; - return """"; +Func GetDefaultValue = defval => { + if (string.IsNullOrEmpty(defval)) return """"; + return "" = "" + defval + "";""; }; }@{ switch (gen.fsql.Ado.DataType) { @@ -68,8 +68,8 @@ namespace @gen.NameSpace { @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } - @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") - @:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(col) + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") + @:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(gen.GetColumnDefaultValue(col, false)) @: } } @@ -89,9 +89,13 @@ var gen = Model as RazorModel; var fks = gen.table.Foreigns; Func GetAttributeString = attr => { - if (string.IsNullOrEmpty(attr)) return null; + if (string.IsNullOrEmpty(attr)) return """"; return string.Concat("", "", attr.Trim('[', ']')); }; +Func GetDefaultValue = defval => { + if (string.IsNullOrEmpty(defval)) return """"; + return "" = "" + defval + "";""; +}; Func GetFkObjectName = fkx => { var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); @@ -155,9 +159,9 @@ namespace @gen.NameSpace { @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } - @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") if (findfks.Any() == false) { - @:public @gen.GetCsType(col) @csname { get; set; } + @:public @gen.GetCsType(col) @csname { get; set; }@GetDefaultValue(gen.GetColumnDefaultValue(col, false)) } else { @:public @gen.GetCsType(col) @csname { get => _@csname; set { @:if (_@csname == value) return; @@ -166,7 +170,7 @@ namespace @gen.NameSpace { @:@gen.GetCsName(GetFkObjectName(fkcok2)) = null; } @:} } - @:private @gen.GetCsType(col) _@csname; + @:private @gen.GetCsType(col) _@csname@GetDefaultValue(gen.GetColumnDefaultValue(col, false)).TrimEnd(';'); } @: } diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index e2be6979..85296c72 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -1,4 +1,7 @@ -using FreeSql.DatabaseModel; +using FreeSql; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; +using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Linq; @@ -50,7 +53,8 @@ public class RazorModel { } #region 特性 - public string GetTableAttribute() { + public string GetTableAttribute() + { var sb = new List(); if (GetCsName(this.FullTableName) != this.FullTableName) @@ -61,10 +65,12 @@ public class RazorModel { sb.Add("Name = \"" + this.FullTableName + "\""); //Todo: QuoteSqlName } + sb.Add("DisableSyncStructure = true"); if (sb.Any() == false) return null; return "[Table(" + string.Join(", ", sb) + ")]"; } - public string GetColumnAttribute(DbColumnInfo col) { + public string GetColumnAttribute(DbColumnInfo col, bool isInsertValueSql = false) + { var sb = new List(); if (GetCsName(col.Name) != col.Name) @@ -74,7 +80,98 @@ public class RazorModel { { var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); if (dbinfo != null && string.Compare(dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim(), col.DbTypeTextFull, true) != 0) - sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + { + #region StringLength 反向 + switch (fsql.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + switch (col.DbTypeTextFull.ToLower()) + { + case "longtext": sb.Add("StringLength = -2"); break; + case "text": sb.Add("StringLength = -1"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + switch (col.DbTypeTextFull.ToLower()) + { + case "nvarchar(max)": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: + case DataType.ShenTong: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Oracle: + case DataType.OdbcOracle: + switch (col.DbTypeTextFull.ToLower()) + { + case "nclob": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar2\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Dameng: + case DataType.OdbcDameng: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar2\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Sqlite: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.MsAccess: + switch (col.DbTypeTextFull.ToLower()) + { + case "longtext": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + } + #endregion + } if (col.IsPrimary) sb.Add("IsPrimary = true"); if (col.IsIdentity) @@ -87,15 +184,75 @@ public class RazorModel { if (col.IsNullable == false && fsql.DbFirst.GetCsType(col).Contains("?") == true) sb.Add("IsNullable = false"); } + + if (isInsertValueSql) + { + var defval = GetColumnDefaultValue(col, false); + if (defval == null) //c#默认属性值,就不需要设置 InsertValueSql 了 + { + defval = GetColumnDefaultValue(col, true); + if (defval != null) + { + sb.Add("InsertValueSql = \"" + defval.Replace("\"", "\\\"") + "\""); + sb.Add("CanInsert = false"); + } + } + else + sb.Add("CanInsert = false"); + } } if (sb.Any() == false) return null; return "[Column(" + string.Join(", ", sb) + ")]"; } + public string GetColumnDefaultValue(DbColumnInfo col, bool isInsertValueSql) + { + var defval = col.DefaultValue?.Trim(); + if (string.IsNullOrEmpty(defval)) return null; + var cstype = col.CsType.NullableTypeOrThis(); + if (fsql.Ado.DataType == DataType.SqlServer || fsql.Ado.DataType == DataType.OdbcSqlServer) + { + if (defval.StartsWith("((") && defval.EndsWith("))")) defval = defval.Substring(2, defval.Length - 4); + else if (defval.StartsWith("('") && defval.EndsWith("')")) defval = defval.Substring(2, defval.Length - 4).Replace("''", "'"); + else if (defval.StartsWith("(") && defval.EndsWith(")")) defval = defval.Substring(1, defval.Length - 2); + else return null; + } + else if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || + cstype == typeof(Guid) && defval.StartsWith("'") && defval.EndsWith("'::uuid") + ) && (fsql.Ado.DataType == DataType.PostgreSQL || fsql.Ado.DataType == DataType.OdbcPostgreSQL || + fsql.Ado.DataType == DataType.OdbcKingbaseES || + fsql.Ado.DataType == DataType.ShenTong)) + { + defval = defval.Substring(1, defval.LastIndexOf("'::") - 1).Replace("''", "'"); + } + else if (defval.StartsWith("'") && defval.EndsWith("'")) + { + defval = defval.Substring(1, defval.Length - 2).Replace("''", "'"); + if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) defval = defval.Replace("\\\\", "\\"); + } + if (cstype.IsNumberType() && decimal.TryParse(defval, out var trydec)) + { + if (isInsertValueSql) return defval; + if (cstype == typeof(float)) return defval + "f"; + if (cstype == typeof(double)) return defval + "d"; + if (cstype == typeof(decimal)) return defval + "M"; + return defval; + } + if (cstype == typeof(Guid) && Guid.TryParse(defval, out var tryguid)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"Guid.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(DateTime) && DateTime.TryParse(defval, out var trydt)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"DateTime.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(TimeSpan) && TimeSpan.TryParse(defval, out var tryts)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"TimeSpan.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; + if (cstype == typeof(bool)) return isInsertValueSql ? defval : (defval == "1" || defval == "t" ? "true" : "false"); + if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + if (isInsertValueSql) return (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval); + return isInsertValueSql ? defval : null; //sql function or exp + } #endregion #region mysql enum/set - public string GetMySqlEnumSetDefine() { - if (fsql.Ado.DataType != FreeSql.DataType.MySql) return null; + public string GetMySqlEnumSetDefine() + { + if (fsql.Ado.DataType != FreeSql.DataType.MySql && fsql.Ado.DataType != FreeSql.DataType.OdbcMySql) return null; var sb = new StringBuilder(); foreach (var col in table.Columns) { if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) { @@ -150,4 +307,7 @@ Unknow{1}", str2.Replace("\"", "\\\""), ++unknow_idx); #endregion } +[Table(DisableSyncStructure = true)] +class TestTb { public Guid id { get; set; } } +