Compare commits

...

6 Commits

14 changed files with 84 additions and 33 deletions

View File

@ -38,9 +38,9 @@
<ItemGroup>
<PackageReference Include="IBM.Data.DB2.Core" Version="3.1.0.600" />
<PackageReference Include="MySqlConnector" Version="2.4.0" />
<PackageReference Include="NewLife.Redis" Version="6.3.2025.701" />
<PackageReference Include="NewLife.Remoting" Version="3.3.2025.701" />
<PackageReference Include="NewLife.Stardust" Version="3.4.2025.701" />
<PackageReference Include="NewLife.Redis" Version="6.3.2025.801" />
<PackageReference Include="NewLife.Remoting" Version="3.4.2025.801" />
<PackageReference Include="NewLife.Stardust" Version="3.4.2025.801" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.9.1" />
<PackageReference Include="SapHana.DotNetCore.Data.Provider" Version="2.11.14" />
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />

View File

@ -720,7 +720,9 @@ public class EntityBuilder : ClassBuilder
if (!dc.ItemType.IsNullOrEmpty()) sb.AppendFormat(", ItemType = \"{0}\"", dc.ItemType);
// 支持生成带精度的特性
if (dc.Precision > 0 || dc.Scale > 0) sb.AppendFormat(", Precision = {0}, Scale = {1}", dc.Precision, dc.Scale);
var def = ModelHelper.FixDefaultByType(dc.Clone(dc.Table), dc);
if (dc.Precision > 0 && dc.Precision != def.Precision) sb.AppendFormat(", Precision = {0}", dc.Precision);
if (dc.Scale > 0 && dc.Scale != def.Scale) sb.AppendFormat(", Scale = {0}", dc.Scale);
// 默认值
if (!dc.DefaultValue.IsNullOrEmpty()) sb.AppendFormat(", DefaultValue = \"{0}\"", dc.DefaultValue);

View File

@ -176,7 +176,8 @@ public class HtmlBuilder : ClassBuilder
else
WriteLine("<td></td>");
if (column.Precision > 0 || column.Scale > 0)
var def = ModelHelper.FixDefaultByType(column.Clone(column.Table), column);
if (column.Precision > 0 && column.Precision != def.Precision || column.Scale > 0 && column.Scale != def.Scale)
WriteLine("<td>({0}, {1})</td>", column.Precision, column.Scale);
else
WriteLine("<td></td>");

View File

@ -363,7 +363,7 @@ internal class HanaMetaData : RemoteDbMetaData
#region
protected override List<IDataTable> OnGetTables(String[] names)
protected override List<IDataTable> OnGetTables(String[]? names)
{
var ss = Database.CreateSession();
var db = Database.DatabaseName;
@ -401,13 +401,14 @@ internal class HanaMetaData : RemoteDbMetaData
field.ColumnName = dc["Field"] + "";
field.RawType = dc["Type"] + "";
field.Description = dc["Comment"] + "";
field.DefaultValue = dc["Default"] as String;
if (dc["Extra"] + "" == "auto_increment") field.Identity = true;
if (dc["Key"] + "" == "PRI") field.PrimaryKey = true;
if (dc["Null"] + "" == "YES") field.Nullable = true;
field.Length = field.RawType.Substring("(", ")").ToInt();
field.DataType = GetDataType(field);
field.DataType = GetDataType(field)!;
if (field.DataType == null)
{

View File

@ -342,19 +342,23 @@ internal class HighGoMetaData : RemoteDbMetaData
{
var field = table.CreateColumn();
field.ColumnName = $"{dc["ColumnName"]}";
field.RawType = $"{dc["DataType"]}";
field.Description = $"{dc["ColumnDescription"]}";
field.ColumnName = dc["ColumnName"] + "";
field.RawType = dc["DataType"] as String;
field.Description = dc["ColumnDescription"] as String;
//field.DefaultValue = dc["Default"] as String;
field.Identity = dc["IsIdentity"].ToBoolean();
field.PrimaryKey = dc["IsPrimaryKey"].ToBoolean();
field.Nullable = dc["IsNullable"].ToBoolean();
//field.Precision = dc["Precision"].ToInt();
//field.Scale = dc["Scale"].ToInt();
field.Length = dc["Length"].ToInt();
var type = GetDataType(field);
field.DataType = type;
field.DataType = GetDataType(field)!;
field.Fix();
table.Columns.Add(field);
}
}
@ -430,7 +434,8 @@ internal class HighGoMetaData : RemoteDbMetaData
public override String DropTableDescriptionSQL(IDataTable table) => $"COMMENT ON TABLE {FormatName(table)} IS NULL";
public override String AddColumnDescriptionSQL(IDataColumn field)
{
if (String.IsNullOrEmpty(field.Description)) { return null; };
if (String.IsNullOrEmpty(field.Description)) { return null; }
;
return $"COMMENT ON COLUMN {FormatName(field.Table)}.{FormatName(field)} IS '{field.Description}'";
}
public override String DropColumnDescriptionSQL(IDataColumn field) => $"COMMENT ON COLUMN {FormatName(field.Table)}.{FormatName(field)} IS NULL";

View File

@ -372,16 +372,20 @@ internal class KingBaseMetaData : RemoteDbMetaData
field.ColumnName = $"{dc["ColumnName"]}";
field.RawType = $"{dc["DataType"]}";
field.Description = $"{dc["ColumnDescription"]}";
//field.DefaultValue = dc["Default"] as String;
field.Identity = dc["IsIdentity"].ToBoolean();
field.PrimaryKey = dc["IsPrimaryKey"].ToBoolean();
field.Nullable = dc["IsNullable"].ToBoolean();
//field.Precision = dc["Precision"].ToInt();
//field.Scale = dc["Scale"].ToInt();
field.Length = dc["Length"].ToInt();
var type = GetDataType(field);
field.DataType = type;
field.DataType = GetDataType(field)!;
field.Fix();
table.Columns.Add(field);
}
}

View File

@ -479,8 +479,19 @@ internal class MySqlMetaData : RemoteDbMetaData
if (dc["COLUMN_KEY"] + "" == "PRI") field.PrimaryKey = true;
if (dc["IS_NULLABLE"] + "" == "YES") field.Nullable = true;
// 精度 与 位数
field.Precision = dc["NUMERIC_PRECISION"].ToInt();
field.Scale = dc["NUMERIC_SCALE"].ToInt();
field.DefaultValue = dc["COLUMN_DEFAULT"] as String;
field.Length = field.RawType.Substring("(", ")").ToInt();
// 在MySql8.0中COLUMN_TYPE取得的类型数字类型已经没有圆括号精度需要额外处理
//if (field.Length == 0 && field.RawType.EqualIgnoreCase("int", "bigint", "tinyint", "datetime"))
//{
// field.Precision = dc["NUMERIC_PRECISION"].ToInt();
//}
var type = GetDataType(field);
if (type == null)
{
@ -508,13 +519,14 @@ internal class MySqlMetaData : RemoteDbMetaData
field.ColumnName = dc["Field"] + "";
field.RawType = dc["Type"] + "";
field.Description = dc["Comment"] + "";
field.DefaultValue = dc["Default"] as String;
if (dc["Extra"] + "" == "auto_increment") field.Identity = true;
if (dc["Key"] + "" == "PRI") field.PrimaryKey = true;
if (dc["Null"] + "" == "YES") field.Nullable = true;
field.Length = field.RawType.Substring("(", ")").ToInt();
field.DataType = GetDataType(field);
field.DataType = GetDataType(field)!;
if (field.DataType == null)
{

View File

@ -550,7 +550,7 @@ internal class SQLiteMetaData : FileDbMetaData
}
static readonly Regex _reg = new("""(?:^|,)\s*("[^"]+"|\[\w+\]|\w+)\s*(\w+(?:\(\d+(?:,\s*\d+)?\))?)\s*([^,]*)?""",
RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase);
RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase);
public void ParseColumns(IDataTable table, String sqlCreateTable)
{
if (sqlCreateTable.StartsWithIgnoreCase("create table"))
@ -604,7 +604,7 @@ internal class SQLiteMetaData : FileDbMetaData
field.Scale = ns[1];
}
}
field.DataType = GetDataType(field);
field.DataType = GetDataType(field)!;
// 如果数据库里面是integer或者autoincrement识别类型是Int64又是自增则改为Int32保持与大多数数据库的兼容
if (field.Identity && field.DataType == typeof(Int64) && field.RawType.EqualIgnoreCase("integer", "autoincrement"))
@ -659,12 +659,13 @@ internal class SQLiteMetaData : FileDbMetaData
foreach (var row in ds.Rows)
{
var field = table.CreateColumn();
field.ColumnName = row[1].ToString().Replace(" ", "");
field.RawType = row[2].ToString().Replace(" ", "");//去除所有空格
field.ColumnName = row[1]!.ToString().Replace(" ", "");
field.RawType = row[2]!.ToString().Replace(" ", "");//去除所有空格
field.Nullable = row[3].ToInt() != 1;
field.DefaultValue = row[4] as String;
field.PrimaryKey = row[5].ToInt() == 1;
field.DataType = GetDataType(field);
field.DataType = GetDataType(field)!;
if (field.DataType == null)
{
if (field.RawType.StartsWithIgnoreCase("varchar2", "nvarchar2")) field.DataType = typeof(String);

View File

@ -211,12 +211,12 @@ partial class DbMetaData
// 长度
field.Length = GetDataRowValue<Int32>(dr, "CHARACTER_MAXIMUM_LENGTH", "LENGTH", "COLUMN_SIZE");
if (field is XField fi)
//if (field is XField fi)
{
// 精度 与 位数
fi.Precision = GetDataRowValue<Int32>(dr, "NUMERIC_PRECISION", "DATETIME_PRECISION", "PRECISION");
fi.Scale = GetDataRowValue<Int32>(dr, "NUMERIC_SCALE", "SCALE");
if (field.Length == 0) field.Length = fi.Precision;
field.Precision = GetDataRowValue<Int32>(dr, "NUMERIC_PRECISION", "DATETIME_PRECISION", "PRECISION");
field.Scale = GetDataRowValue<Int32>(dr, "NUMERIC_SCALE", "SCALE");
if (field.Length == 0) field.Length = field.Precision;
}
// 允许空
@ -231,6 +231,9 @@ partial class DbMetaData
if (!String.IsNullOrEmpty(str)) field.Nullable = "Y".EqualIgnoreCase(str);
}
// 默认值
field.DefaultValue = GetDataRowValue<String>(dr, "COLUMN_DEFAULT");
// 描述
field.Description = GetDataRowValue<String>(dr, "DESCRIPTION");
@ -421,7 +424,7 @@ partial class DbMetaData
{
case "Int64":
type = typeof(Int64);
break;
break;
default:
type = typeof(Int32);
break;

View File

@ -775,7 +775,7 @@ public static class ModelHelper
/// <param name="dc"></param>
/// <param name="oridc"></param>
/// <returns></returns>
private static IDataColumn FixDefaultByType(this IDataColumn dc, IDataColumn? oridc)
public static IDataColumn FixDefaultByType(this IDataColumn dc, IDataColumn? oridc)
{
if (dc.DataType == null) return dc;
@ -784,43 +784,63 @@ public static class ModelHelper
case TypeCode.Boolean:
dc.RawType = "bit";
dc.Nullable = false;
dc.Precision = 0;
dc.Scale = 0;
break;
case TypeCode.Byte:
case TypeCode.Char:
case TypeCode.SByte:
dc.RawType = "tinyint";
dc.Nullable = false;
dc.Precision = 3;
dc.Scale = 0;
break;
case TypeCode.DateTime:
dc.RawType = "datetime";
dc.Nullable = true;
dc.Precision = 0;
dc.Scale = 0;
break;
case TypeCode.Int16:
case TypeCode.UInt16:
dc.RawType = "smallint";
dc.Nullable = false;
dc.Precision = 5;
dc.Scale = 0;
break;
case TypeCode.Int32:
case TypeCode.UInt32:
dc.RawType = "int";
dc.Nullable = false;
dc.Precision = 10;
dc.Scale = 0;
break;
case TypeCode.Int64:
case TypeCode.UInt64:
dc.RawType = "bigint";
dc.Nullable = false;
dc.Precision = oridc != null && oridc.RawType == "bigint unsigned" ? 20 : 19;
dc.Scale = 0;
break;
case TypeCode.Single:
dc.RawType = "real";
dc.Nullable = false;
dc.Precision = 12;
dc.Scale = 2;
break;
case TypeCode.Double:
dc.RawType = "float";
dc.Nullable = false;
dc.Precision = 22;
dc.Scale = 4;
break;
case TypeCode.Decimal:
dc.RawType = "money";
dc.Nullable = false;
//dc.Precision = 20;
//dc.Scale = 4;
dc.Precision = 0;
dc.Scale = 0;
break;
case TypeCode.String:
// 原来就是普通字符串或者非ntext字符串一律转nvarchar
@ -853,6 +873,8 @@ public static class ModelHelper
}
}
dc.Nullable = true;
dc.Precision = 0;
dc.Scale = 0;
break;
default:
if (dc.DataType == typeof(Byte[]))
@ -864,7 +886,7 @@ public static class ModelHelper
}
// 默认值里面不要设置数据类型,否则写入模型文件的时候会漏掉数据类型
dc.DataType = null;
dc.DataType = null!;
if (dc.RawType.IsNullOrEmpty()) dc.RawType = null;
return dc;

Binary file not shown.

View File

@ -7,7 +7,7 @@
<Description>数据中间件支持MySQL、SQLite、SqlServer、Oracle、Postgresql、TDengine、达梦重点在缓存、性能、分表、自动建表。</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2025 NewLife</Copyright>
<VersionPrefix>11.19</VersionPrefix>
<VersionPrefix>11.20</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>
@ -31,7 +31,7 @@
<RepositoryUrl>https://github.com/NewLifeX/X</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>新生命团队;X组件;NewLife;$(AssemblyName)</PackageTags>
<PackageReleaseNotes>支持2024行政区划</PackageReleaseNotes>
<PackageReleaseNotes>改进二进制序列化及内存占用提升实体列表文件缓存性能支持AI机器学习改进精度位数以及默认值的正反向工程和代码生成</PackageReleaseNotes>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
@ -46,7 +46,7 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="NewLife.Core" Version="11.5.2025.724-beta1743" />
<PackageReference Include="NewLife.Core" Version="11.6.2025.801" />
</ItemGroup>
<ItemGroup>
<Using Include="NewLife" />

View File

@ -8,7 +8,7 @@
<Description>数据中间件,代码生成</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2025 NewLife</Copyright>
<VersionPrefix>11.18</VersionPrefix>
<VersionPrefix>11.20</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>

View File

@ -85,7 +85,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="NewLife.Core" Version="11.5.2025.724-beta1743" />
<PackageReference Include="NewLife.Core" Version="11.6.2025.801" />
<PackageReference Include="NewLife.IP" Version="2.3.2025.601" />
<PackageReference Include="NewLife.UnitTest" Version="1.0.2025.101" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.7" />