diff --git a/FreeSql.Tests/DataAnnotations/FluentTest.cs b/FreeSql.Tests/DataAnnotations/FluentTest.cs new file mode 100644 index 00000000..5c5ae522 --- /dev/null +++ b/FreeSql.Tests/DataAnnotations/FluentTest.cs @@ -0,0 +1,45 @@ +using FreeSql.DataAnnotations; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations { + public class FluentTest { + [Fact] + public void Fluent() { + g.mysql.CodeFirst + .ConfigEntity(a => { + a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); + a.Property(b => b.Id).Name("Id22").IsIdentity(true); + a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + }) + .ConfigEntity(a => { + a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); + a.Property(b => b.Id).Name("Id22").IsIdentity(true); + a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + }); + + var ddl1 = g.mysql.CodeFirst.GetComparisonDDLStatements(); + var ddl2 = g.mysql.CodeFirst.GetComparisonDDLStatements(); + + var t1id = g.mysql.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); + var t1 = g.mysql.Select(t1id).ToOne(); + + var t2lastId = g.mysql.Select().Max(a => a.Id); + var t2affrows = g.mysql.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); + var t2 = g.mysql.Select(t2lastId + 1).ToOne(); + } + } + + class TestFluenttb1 { + public int Id { get; set; } + + public string name { get; set; } = "defaultValue"; + } + + [Table(Name = "cccccdddwww")] + class TestFluenttb2 { + [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] + public int Id { get; set; } + + public string name { get; set; } = "defaultValue"; + } +} diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 1bbeef54..beda3238 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -85,8 +85,7 @@ namespace FreeSql.Tests.MySql { [Fact] public void Lazy() { - //Type.GetType(); - var sql = g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx").LeftJoin(a => a.Parent_id == a.Parent.Id).ToList(); var songs = g.mysql.Select().Limit(10).ToList(); diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 15750ffd..a730f424 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -16,18 +16,19 @@ namespace FreeSql.DataAnnotations { /// public string DbType { get; set; } + internal bool? _IsPrimary, _IsIdentity, _IsNullable; /// /// 主键 /// - public bool IsPrimary { get; set; } + public bool IsPrimary { get => _IsPrimary ?? false; set => _IsPrimary = value; } /// /// 自增标识 /// - public bool IsIdentity { get; set; } + public bool IsIdentity { get => _IsIdentity ?? false; set => _IsIdentity = value; } /// /// 是否可DBNull /// - public bool IsNullable { get; set; } + public bool IsNullable { get => _IsNullable ?? false; set => _IsNullable = value; } /// /// 数据库默认值 diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs new file mode 100644 index 00000000..3b9ffe56 --- /dev/null +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -0,0 +1,54 @@ +using System; + +namespace FreeSql.DataAnnotations { + public class ColumnFluent { + + public ColumnFluent(ColumnAttribute column) { + _column = column; + } + + ColumnAttribute _column; + /// + /// 数据库列名 + /// + public ColumnFluent Name(string value) { + _column.Name = value; + return this; + } + /// + /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + /// + public ColumnFluent OldName(string value) { + _column.OldName = value; + return this; + } + /// + /// 数据库类型,如: varchar(255) + /// + public ColumnFluent DbType(string value) { + _column.DbType = value; + return this; + } + + /// + /// 主键 + /// + public ColumnFluent IsPrimary(bool value) { + _column.IsPrimary = value; + return this; + } + /// 自增标识 + /// + public ColumnFluent IsIdentity(bool value) { + _column.IsIdentity = value; + return this; + } + /// + /// 是否可DBNull + /// + public ColumnFluent IsNullable(bool value) { + _column.IsNullable = value; + return this; + } + } +} diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index c2773633..65afe1e5 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; namespace FreeSql.DataAnnotations { public class TableAttribute : Attribute { @@ -15,5 +16,7 @@ namespace FreeSql.DataAnnotations { /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 /// public string SelectFilter { get; set; } + + internal ConcurrentDictionary _columns = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs new file mode 100644 index 00000000..2860f1df --- /dev/null +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq.Expressions; + +namespace FreeSql.DataAnnotations { + public class TableFluent { + + public TableFluent(TableAttribute table) { + _table = table; + } + + TableAttribute _table; + /// + /// 数据库表名 + /// + public TableFluent Name(string value) { + _table.Name = value; + return this; + } + /// + /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + /// + public TableFluent OldName(string value) { + _table.OldName = value; + return this; + } + /// + /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + /// + public TableFluent SelectFilter(string value) { + _table.SelectFilter = value; + return this; + } + + public ColumnFluent Property(Expression> column) { + var proto = (column.Body as MemberExpression)?.Member; + if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); + var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); + return new ColumnFluent(col); + } + } +} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index c17fb21c..39f75ddb 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -5,10 +5,26 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; +using System.Linq; using System.Reflection; public static class FreeSqlGlobalExtensions { + static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary { + [typeof(sbyte)] = true, + [typeof(short)] = true, + [typeof(int)] = true, + [typeof(long)] = true, + [typeof(byte)] = true, + [typeof(ushort)] = true, + [typeof(uint)] = true, + [typeof(ulong)] = true, + [typeof(double)] = true, + [typeof(float)] = true, + [typeof(decimal)] = true + }); + public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that.GenericTypeArguments.FirstOrDefault() ?? that); + /// /// 测量两个经纬度的距离,返回单位:米 /// diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index fefe2ba6..11dc386a 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -3,6 +3,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text; using System.Threading; diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 527646a0..e333da97 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.DataAnnotations; +using System; namespace FreeSql { public interface ICodeFirst { @@ -48,5 +49,6 @@ namespace FreeSql { /// /// (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + ICodeFirst ConfigEntity(Action> entity); } } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 0f778e52..a946ea2d 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -194,8 +194,11 @@ namespace FreeSql.Internal { for (var a = tbidx + 1; a < _tables.Count; a++) _tables[a].Type = SelectTableInfoType.From; } else { - var find = _tables.Where((a, c) => c > 0 && a.Type == tbtype && string.IsNullOrEmpty(a.On)).LastOrDefault(); - if (find != null) find.On = filter; + var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault(); + if (find != null) { + find.Type = tbtype; + find.On = filter; + } } } @@ -355,13 +358,13 @@ namespace FreeSql.Internal { if (isQuoteName) name = _common.QuoteSqlName(name); return name; } - Func getOrAddTable = (tbtmp, alias) => { - var finds = _tables.Where((a2, c2) => a2.Table.CsName == tbtmp.CsName).ToArray(); //外部表,内部表一起查 + Func getOrAddTable = (tbtmp, alias, isa) => { + var finds = _tables.Where((a2, c2) => (isa || c2 > 0) && a2.Table.CsName == tbtmp.CsName).ToArray(); //外部表,内部表一起查 if (finds.Length > 1) { finds = _tables.Where((a2, c2) => a2.Table.CsName == tbtmp.CsName && a2.Type == SelectTableInfoType.Parent && a2.Alias == $"__parent_{alias}_parent__").ToArray(); //查询外部表 if (finds.Any() == false) { - finds = _tables.Where((a2, c2) => a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表 - if (finds.Length > 1) finds = _tables.Where((a2, c2) => a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); + finds = _tables.Where((a2, c2) => (isa || c2 > 0) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表 + if (finds.Length > 1) finds = _tables.Where((a2, c2) => (isa || c2 > 0) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); } } var find = finds.FirstOrDefault(); @@ -388,7 +391,7 @@ namespace FreeSql.Internal { if (tb2tmp != null) { if (exp2.NodeType == ExpressionType.Parameter) alias2 = (exp2 as ParameterExpression).Name; else alias2 = $"{alias2}__{mp2.Member.Name}"; - find2 = getOrAddTable(tb2tmp, alias2); + find2 = getOrAddTable(tb2tmp, alias2, exp2.NodeType == ExpressionType.Parameter); alias2 = find2.Alias; tb2 = tb2tmp; } @@ -397,7 +400,7 @@ namespace FreeSql.Internal { if (_selectColumnMap != null) { var tb3 = _common.GetTableByEntity(mp2.Type); if (tb3 != null) { - var find3 = getOrAddTable(tb2tmp, $"{alias2}__{mp2.Member.Name}"); + var find3 = getOrAddTable(tb2tmp, $"{alias2}__{mp2.Member.Name}", exp2.NodeType == ExpressionType.Parameter); foreach (var tb3c in tb3.Columns.Values) _selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c }); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 758379c1..7464c2c7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -283,8 +283,8 @@ namespace FreeSql.Internal.CommonProvider { if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); else dicfield.Add(quoteName, true); } else { - var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault(); - if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault(); + var tb2 = _tables.Where((a, b) => b > 0 && a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系 + if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where((a, b) => b > 0 && a.Table.Type == prop.PropertyType).FirstOrDefault(); if (tb2 == null) continue; foreach (var col2 in tb2.Table.Columns.Values) { if (index > 0) field.Append(", "); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 67b3b1f8..f91809a6 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -74,7 +74,7 @@ namespace FreeSql.Internal.CommonProvider { var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, cols, binaryExpression, null); if (cols.Any() == false) return this; foreach (var col in cols) { - if (col.Column.Attribute.IsNullable) { + if (col.Column.Attribute.IsNullable == true) { var replval = _orm.CodeFirst.GetDbInfo(col.Column.CsType.GenericTypeArguments.FirstOrDefault())?.defaultValue; if (replval == null) continue; var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index d559eb33..dfe91af9 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -1,6 +1,8 @@ -using FreeSql.Internal.Model; +using FreeSql.DataAnnotations; +using FreeSql.Internal.Model; using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.Common; using System.Linq; @@ -30,11 +32,45 @@ namespace FreeSql.Internal { _orm = orm; } + ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); + internal ICodeFirst ConfigEntity(Action> entity) { + var type = typeof(T); + var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); + var fluent = new TableFluent(table); + entity?.Invoke(fluent); + return _orm.CodeFirst; + } + internal TableAttribute GetEntityTableAttribute(Type entityType) { + var attr = entityType.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute; + if (dicConfigEntity.TryGetValue(entityType, out var trytb) == false) return attr; + if (attr == null) attr = new TableAttribute(); + + if (string.IsNullOrEmpty(attr.Name)) attr.Name = trytb.Name; + if (string.IsNullOrEmpty(attr.OldName)) attr.OldName = trytb.OldName; + if (string.IsNullOrEmpty(attr.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; + return attr; + } + internal ColumnAttribute GetEntityColumnAttribute(Type entityType, PropertyInfo proto) { + var attr = proto.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute; + if (dicConfigEntity.TryGetValue(entityType, out var trytb) == false) return attr; + if (trytb._columns.TryGetValue(proto.Name, out var trycol) == false) return attr; + if (attr == null) attr = new ColumnAttribute(); + + if (string.IsNullOrEmpty(attr.Name)) attr.Name = trycol.Name; + if (string.IsNullOrEmpty(attr.OldName)) attr.OldName = trycol.OldName; + if (string.IsNullOrEmpty(attr.DbType)) attr.DbType = trycol.DbType; + if (attr._IsPrimary == null) attr._IsPrimary = trycol.IsPrimary; + if (attr._IsIdentity == null) attr._IsIdentity = trycol.IsIdentity; + if (attr._IsNullable == null) attr._IsNullable = trycol.IsNullable; + if (attr.DbDefautValue == null) attr.DbDefautValue = trycol.DbDefautValue; + return attr; + } + internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) { if (dywhere == null) return ""; var type = dywhere.GetType(); - var primarys = table.Columns.Values.Where(a => a.Attribute.IsPrimary).ToArray(); - if (primarys.Length == 1 && type == primarys.First().CsType) { + var primarys = table.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + if (primarys.Length == 1 && (type == primarys.First().CsType || type.IsNumberType() && primarys.First().CsType.IsNumberType())) { return $"{aliasAndDot}{this.QuoteSqlName(primarys.First().Attribute.Name)} = {this.FormatSql("{0}", dywhere)}"; } else if (primarys.Length > 0 && type.FullName == table.Type.FullName) { var sb = new StringBuilder(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a686fd93..8e4b09e7 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -30,7 +30,7 @@ namespace FreeSql.Internal { if (tbc.TryGetValue(entity, out var trytb)) return trytb; if (common.CodeFirst.GetDbInfo(entity) != null) return null; - var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute; + var tbattr = common.GetEntityTableAttribute(entity); trytb = new TableInfo(); trytb.Type = entity; trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); @@ -46,7 +46,7 @@ namespace FreeSql.Internal { foreach (var p in trytb.Properties.Values) { var tp = common.CodeFirst.GetDbInfo(p.PropertyType); //if (tp == null) continue; - var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute; + var colattr = common.GetEntityColumnAttribute(entity, p); if (tp == null && colattr == null) { if (common.CodeFirst.IsLazyLoading) { var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; @@ -72,7 +72,7 @@ namespace FreeSql.Internal { if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); - if ((colattr.IsNullable == false || colattr.IsIdentity || colattr.IsPrimary) && colattr.DbType.Contains("NOT NULL") == false) { + if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { colattr.IsNullable = false; colattr.DbType += " NOT NULL"; } @@ -89,10 +89,7 @@ namespace FreeSql.Internal { var consturctorType = p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType; colattr.DbDefautValue = Activator.CreateInstance(consturctorType); } - if (colattr.IsIdentity && new[] { - typeof(sbyte), typeof(short), typeof(int), typeof(long), - typeof(byte), typeof(ushort), typeof(uint), typeof(ulong), - typeof(double), typeof(float), typeof(decimal) }.Contains(p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType) == false) + if (colattr.IsIdentity == true && (p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType)?.IsNumberType() == false) colattr.IsIdentity = false; var col = new ColumnInfo { @@ -104,9 +101,9 @@ namespace FreeSql.Internal { trytb.Columns.Add(colattr.Name, col); trytb.ColumnsByCs.Add(p.Name, col); } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray(); foreach (var col in trytb.Primarys) col.Attribute.IsPrimary = true; } diff --git a/FreeSql/Internal/UtilsReflection.cs b/FreeSql/Internal/UtilsReflection.cs index 0018e85e..25d60fe3 100644 --- a/FreeSql/Internal/UtilsReflection.cs +++ b/FreeSql/Internal/UtilsReflection.cs @@ -57,7 +57,7 @@ namespace FreeSql.Internal { if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); - if ((colattr.IsNullable == false || colattr.IsIdentity || colattr.IsPrimary) && colattr.DbType.Contains("NOT NULL") == false) { + if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { colattr.IsNullable = false; colattr.DbType += " NOT NULL"; } @@ -84,9 +84,9 @@ namespace FreeSql.Internal { trytb.Columns.Add(colattr.Name, col); trytb.ColumnsByCs.Add(p.Name, col); } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray(); foreach(var col in trytb.Primarys) col.Attribute.IsPrimary = true; } diff --git a/FreeSql/MySql/MySqlCodeFirst.cs b/FreeSql/MySql/MySqlCodeFirst.cs index 6d0471e4..9d1b9446 100644 --- a/FreeSql/MySql/MySqlCodeFirst.cs +++ b/FreeSql/MySql/MySqlCodeFirst.cs @@ -1,4 +1,5 @@ -using FreeSql.DatabaseModel; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; using MySql.Data.MySqlClient; @@ -126,7 +127,7 @@ namespace FreeSql.MySql { foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); sb.Append(","); } if (tb.Primarys.Any() == false) @@ -170,7 +171,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ? if (istmpatler == false) { var existsPrimary = ExecuteScalar(tbname[0], "select 1 from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where table_schema={0} and table_name={1} limit 1".FormatMySql(tbname)); foreach (var tbcol in tb.Columns.Values) { - var isIdentityChanged = tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; + var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || @@ -208,7 +209,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ? foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); sb.Append(","); } if (tb.Primarys.Any() == false) @@ -267,6 +268,6 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ? foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); return affrows > 0; } - + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); } } \ No newline at end of file diff --git a/FreeSql/Oracle/Curd/OracleInsert.cs b/FreeSql/Oracle/Curd/OracleInsert.cs index 72b8291f..8b0a2dd9 100644 --- a/FreeSql/Oracle/Curd/OracleInsert.cs +++ b/FreeSql/Oracle/Curd/OracleInsert.cs @@ -28,7 +28,7 @@ namespace FreeSql.Oracle.Curd { sbtb.Append(_commonUtils.QuoteSqlName(_table.DbName)).Append("("); var colidx = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity) { + if (col.Attribute.IsIdentity == true) { _identCol = col; continue; } diff --git a/FreeSql/Oracle/OracleCodeFirst.cs b/FreeSql/Oracle/OracleCodeFirst.cs index fcc48438..6f4465cd 100644 --- a/FreeSql/Oracle/OracleCodeFirst.cs +++ b/FreeSql/Oracle/OracleCodeFirst.cs @@ -1,4 +1,5 @@ -using FreeSql.DatabaseModel; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; using Oracle.ManagedDataAccess.Client; @@ -106,7 +107,7 @@ namespace FreeSql.Oracle { sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); } if (tb.Primarys.Any() == false) sb.Remove(sb.Length - 1, 1); @@ -184,10 +185,10 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable == false) sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(_commonUtils.FormatSql(" = {0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable ? "" : "NOT").Append(" NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (tbstructcol.column == tbcol.Attribute.OldName) //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); @@ -199,7 +200,7 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } } if (istmpatler == false) { @@ -217,7 +218,7 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname); sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); } if (tb.Primarys.Any() == false) sb.Remove(sb.Length - 1, 1); @@ -305,6 +306,6 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname); foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); return affrows > 0; } - + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); } } \ No newline at end of file diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs index 4ce0d307..2a70df25 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs @@ -16,7 +16,7 @@ namespace FreeSql.PostgreSQL.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity); + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params); return 0; @@ -27,7 +27,7 @@ namespace FreeSql.PostgreSQL.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity); + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params); return 0; diff --git a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs index 9f8e4ea5..c6f2f907 100644 --- a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs +++ b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs @@ -1,4 +1,5 @@ -using FreeSql.DatabaseModel; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; @@ -149,7 +150,7 @@ namespace FreeSql.PostgreSQL { sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); } if (tb.Primarys.Any() == false) sb.Remove(sb.Length - 1, 1); @@ -223,9 +224,9 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (tbstructcol.column == tbcol.Attribute.OldName) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -235,7 +236,7 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0};\r\n", tbcol.Attribute.DbDefautValue)); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } } if (istmpatler == false) { @@ -257,7 +258,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); } if (tb.Primarys.Any() == false) sb.Remove(sb.Length - 1, 1); @@ -319,6 +320,6 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); return affrows > 0; } - + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); } } \ No newline at end of file diff --git a/FreeSql/SqlServer/SqlServerCodeFirst.cs b/FreeSql/SqlServer/SqlServerCodeFirst.cs index 03c325f9..be666e8c 100644 --- a/FreeSql/SqlServer/SqlServerCodeFirst.cs +++ b/FreeSql/SqlServer/SqlServerCodeFirst.cs @@ -8,6 +8,7 @@ using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using FreeSql.DataAnnotations; namespace FreeSql.SqlServer { @@ -123,8 +124,8 @@ namespace FreeSql.SqlServer { foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) sb.Append(" primary key"); sb.Append(","); } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); @@ -188,7 +189,7 @@ use " + database, tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); if (tbcol.Attribute.IsNullable == false) { var addcoldbdefault = tbcol.Attribute.DbDefautValue; if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); @@ -219,10 +220,10 @@ use " + database, tboldname ?? tbname); foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) sb.Append(" primary key"); sb.Append(","); - idents = idents || tbcol.Attribute.IsIdentity; + idents = idents || tbcol.Attribute.IsIdentity == true; } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); @@ -277,6 +278,6 @@ use " + database, tboldname ?? tbname); foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); return affrows > 0; } - + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); } } \ No newline at end of file diff --git a/FreeSql/Sqlite/SqliteCodeFirst.cs b/FreeSql/Sqlite/SqliteCodeFirst.cs index 339bed5f..78808113 100644 --- a/FreeSql/Sqlite/SqliteCodeFirst.cs +++ b/FreeSql/Sqlite/SqliteCodeFirst.cs @@ -1,4 +1,5 @@ -using FreeSql.DatabaseModel; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; using System; @@ -100,7 +101,7 @@ namespace FreeSql.Sqlite { foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { isIndent = true; sb.Append(" PRIMARY KEY AUTOINCREMENT"); } @@ -180,7 +181,7 @@ namespace FreeSql.Sqlite { foreach (var tbcol in tb.Columns.Values) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { isIndent = true; sb.Append(" PRIMARY KEY AUTOINCREMENT"); } @@ -235,6 +236,6 @@ namespace FreeSql.Sqlite { foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); return affrows > 0; } - + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); } } \ No newline at end of file