diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index b7cc6faf..8eb5eb1e 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -17,7 +17,7 @@ namespace FreeSql.DataAnnotations public string OldName { get; set; } /// /// 数据库类型,如: varchar(255) - /// 字符串长度,可使用特性 MaxLength(255) + /// 字符串长度,可使用特性 [MaxLength(255)] /// public string DbType { get; set; } @@ -76,5 +76,26 @@ namespace FreeSql.DataAnnotations /// 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 /// public DateTimeKind ServerTime { get; set; } + + internal int? _StringLength; + /// + /// 设置长度,针对 string 类型避免 DbType 的繁琐设置 + /// 提示:也可以使用 [MaxLength(100)] + /// --- + /// StringLength = 100 时,对应 DbType: + /// MySql -> varchar(100) + /// SqlServer -> nvarchar(100) + /// PostgreSQL -> varchar(100) + /// Oracle -> nvarchar2(100) + /// Sqlite -> nvarchar(100) + /// --- + /// StringLength = -1 时,对应 DbType: + /// MySql -> text + /// SqlServer -> nvarchar(max) + /// PostgreSQL -> text + /// Oracle -> nvarchar2(4000) + /// Sqlite -> text + /// + public int StringLength { get => _StringLength ?? 0; set => _StringLength = value; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index f98d6ffc..e5d6e13c 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -135,5 +135,28 @@ namespace FreeSql.DataAnnotations _column.ServerTime = value; return this; } + + /// + /// 设置长度,针对 string 类型避免 DbType 的繁琐设置 + /// --- + /// StringLength = 100 时,对应 DbType: + /// MySql -> varchar(100) + /// SqlServer -> nvarchar(100) + /// PostgreSQL -> varchar(100) + /// Oracle -> nvarchar2(100) + /// Sqlite -> nvarchar(100) + /// --- + /// StringLength = -1 时,对应 DbType: + /// MySql -> text + /// SqlServer -> nvarchar(max) + /// PostgreSQL -> text + /// Oracle -> nvarchar2(4000) + /// Sqlite -> text + /// + public ColumnFluent StringLength(int value) + { + _column.StringLength = value; + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 768d92dd..3408d4bb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -17,7 +17,7 @@ 数据库类型,如: varchar(255) - 字符串长度,可使用特性 MaxLength(255) + 字符串长度,可使用特性 [MaxLength(255)] @@ -78,6 +78,26 @@ 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + 数据库列名 @@ -159,6 +179,25 @@ + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + 自定义表达式函数解析 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index fef4b9b6..b0fb53be 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -263,34 +263,9 @@ namespace FreeSql if (maxlenAttr != null) { var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval)) + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval != 0) { - if (tryval != 0) - { - switch (ret.Ado.DataType) - { - case DataType.MySql: - case DataType.OdbcMySql: - e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; - break; - case DataType.SqlServer: - case DataType.OdbcSqlServer: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "nvarchar(max)"; - break; - case DataType.PostgreSQL: - case DataType.OdbcPostgreSQL: - e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; - break; - case DataType.Oracle: - case DataType.OdbcOracle: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar2({tryval})" : "nvarchar2(4000)"; - break; - case DataType.Sqlite: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "text"; - break; - - } - } + e.ModifyResult.StringLength = tryval; } } }); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index c533af4e..a2f8d3f0 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -129,6 +129,7 @@ namespace FreeSql.Internal if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; + if (trycol._StringLength != null) attr.StringLength = trycol.StringLength; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -148,6 +149,7 @@ namespace FreeSql.Internal if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; + if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; @@ -163,6 +165,7 @@ namespace FreeSql.Internal if (attr._CanInsert != null) ret = attr; if (attr._CanUpdate != null) ret = attr; if (attr.ServerTime != DateTimeKind.Unspecified) ret = attr; + if (attr._StringLength != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f175d6ae..ee954eaa 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -194,6 +194,38 @@ namespace FreeSql.Internal col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } + if (colattr.MapType == typeof(string) && colattr.StringLength != 0) + { + int strlen = colattr.StringLength; + var charPatten = @"(CHAR|CHAR2|CHARACTER)\s*(\([^\)]*\))?"; + switch (common._orm.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(MAX)"); + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.Oracle: + case DataType.OdbcOracle: + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.Sqlite: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + } + } if (trytb.Columns.ContainsKey(colattr.Name)) throw new Exception($"ColumnAttribute.Name {colattr.Name} 重复存在,请检查(注意:不区分大小写)"); if (trytb.ColumnsByCs.ContainsKey(p.Name)) throw new Exception($"属性名 {p.Name} 重复存在,请检查(注意:不区分大小写)");