Skip to content

Commit 5bb90a9

Browse files
2881028810
authored andcommitted
- 补充 IDbFirst GetTableByDatabase 返回 uk/fk/index 名称,以便迁移;
1 parent 24df5d6 commit 5bb90a9

File tree

11 files changed

+145
-110
lines changed

11 files changed

+145
-110
lines changed

FreeSql.Tests/UnitTest1.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using NpgsqlTypes;
99
using Npgsql.LegacyPostgis;
1010
using System.Linq.Expressions;
11+
using System.Threading.Tasks;
1112

1213
namespace FreeSql.Tests {
1314
public class UnitTest1 {
@@ -51,8 +52,51 @@ class ServiceRequestNew {
5152
public string srvReqstCntt { get; set; }
5253
}
5354

55+
public class TestEntity : EntityBase<int> {
56+
public int Test { get; set; }
57+
public string Title { get; set; }
58+
public override Task Persistent(IRepositoryUnitOfWork uof) {
59+
uof.GetGuidRepository<TestEntity>().Insert(this);
60+
return Task.CompletedTask;
61+
}
62+
public override Task Persistent() {
63+
var res = FreeSqlDb.Insert(this);
64+
res.ExecuteInserted();
65+
return Task.CompletedTask;
66+
}
67+
}
68+
public abstract class EntityBase<TKey> : DomainInfrastructure {
69+
[Column(IsPrimary = true, IsIdentity = true)]
70+
public TKey Id { get; set; }
71+
public Guid CompanyId { get; set; }
72+
[Column(IsVersion = true)]
73+
public int Version { get; set; }
74+
}
75+
76+
public abstract class DomainInfrastructure {
77+
[Column(IsIgnore = true)]
78+
public IFreeSql FreeSqlDb {
79+
get {
80+
return g.sqlite;
81+
}
82+
}
83+
84+
85+
public abstract Task Persistent(IRepositoryUnitOfWork uof);
86+
public abstract Task Persistent();
87+
}
88+
5489
[Fact]
5590
public void Test1() {
91+
92+
var testddd = new TestEntity {
93+
Test = 22,
94+
Title = "xxx"
95+
};
96+
//testddd.Persistent().Wait();
97+
g.sqlite.GetRepository<TestEntity, int>().Insert(testddd);
98+
99+
56100
var testpid1 = g.mysql.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
57101
g.mysql.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
58102

FreeSql/DataAnnotations/ColumnAttribute.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public class ColumnAttribute : Attribute {
3838
/// </summary>
3939
public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; }
4040

41+
/// <summary>
42+
/// 唯一键,多个属性指定相同的标识,代表联合键
43+
/// </summary>
44+
public string Unique { get; set; }
4145
/// <summary>
4246
/// 数据库默认值
4347
/// </summary>

FreeSql/DataAnnotations/ColumnFluent.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ public ColumnFluent IsVersion(bool value) {
6565
return this;
6666
}
6767
/// <summary>
68+
/// 唯一键,多个属性指定相同的标识,代表联合键
69+
/// </summary>
70+
/// <param name="value">标识</param>
71+
/// <returns></returns>
72+
public ColumnFluent Unique(string value) {
73+
_column.Unique = value;
74+
return this;
75+
}
76+
/// <summary>
6877
/// 类型映射,比如:可将 enum 属性映射成 typeof(string)
6978
/// </summary>
7079
/// <param name="type"></param>

FreeSql/DatabaseModel/DBTableInfo.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,19 @@ public class DbTableInfo {
3737
/// <summary>
3838
/// 唯一键/组合
3939
/// </summary>
40-
public List<List<DbColumnInfo>> Uniques { get; internal set; } = new List<List<DbColumnInfo>>();
40+
public Dictionary<string, List<DbColumnInfo>> UniquesDict { get; internal set; } = new Dictionary<string, List<DbColumnInfo>>();
4141
/// <summary>
4242
/// 索引/组合
4343
/// </summary>
44-
public List<List<DbColumnInfo>> Indexes { get; internal set; } = new List<List<DbColumnInfo>>();
44+
public Dictionary<string, List<DbColumnInfo>> IndexesDict { get; internal set; } = new Dictionary<string, List<DbColumnInfo>>();
4545
/// <summary>
4646
/// 外键
4747
/// </summary>
48-
public List<DbForeignInfo> Foreigns { get; internal set; } = new List<DbForeignInfo>();
48+
public Dictionary<string, DbForeignInfo> ForeignsDict { get; internal set; } = new Dictionary<string, DbForeignInfo>();
49+
50+
public IEnumerable<List<DbColumnInfo>> Uniques => UniquesDict.Values;
51+
public IEnumerable<List<DbColumnInfo>> Indexes => IndexesDict.Values;
52+
public IEnumerable<DbForeignInfo> Foreigns => ForeignsDict.Values;
4953
}
5054

5155
public enum DbTableType {

FreeSql/Extensions/EntityUtilExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,15 @@ public static void MapEntityValue(this IFreeSql orm, Type entityType, object ent
264264
Expression.Assign(var2Parm, Expression.TypeAs(parm2, t))
265265
});
266266
foreach (var prop in _table.Properties.Values) {
267+
if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue;
267268
if (_table.ColumnsByCs.ContainsKey(prop.Name)) {
268269
exps.Add(
269270
Expression.Assign(
270271
Expression.MakeMemberAccess(var2Parm, prop),
271272
Expression.MakeMemberAccess(var1Parm, prop)
272273
)
273274
);
274-
} else {
275+
} else if (prop.GetSetMethod() != null) {
275276
exps.Add(
276277
Expression.Assign(
277278
Expression.MakeMemberAccess(var2Parm, prop),

FreeSql/Internal/Model/TableInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class TableInfo {
1313
public Dictionary<string, ColumnInfo> ColumnsByCs { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
1414
public Dictionary<string, ColumnInfo> ColumnsByCsIgnore { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
1515
public ColumnInfo[] Primarys { get; set; }
16+
public Dictionary<string, List<ColumnInfo>> Uniques { get; set; }
1617
public string CsName { get; set; }
1718
public string DbName { get; set; }
1819
public string DbOldName { get; set; }

FreeSql/Internal/UtilsExpressionTree.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
7777
IsIgnore = false,
7878
MapType = p.PropertyType
7979
};
80-
if (colattr._IsNullable == null) colattr._IsNullable = tp.Value.isnullable;
80+
if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable;
8181
if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
8282
colattr.DbType = colattr.DbType.ToUpper();
8383

@@ -164,11 +164,21 @@ internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
164164
trycol.Attribute.IsPrimary = true;
165165
}
166166
}
167+
foreach(var dbuk in dbtb.UniquesDict) {
168+
foreach (var dbcol in dbuk.Value) {
169+
if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType ||
170+
trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) {
171+
trycol.Attribute.Unique = dbuk.Key;
172+
}
173+
}
174+
}
167175
}
168176
}
169177
} catch { }
170178
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
171179
}
180+
trytb.Uniques = trytb.Columns.Values.Where(a => !string.IsNullOrEmpty(a.Attribute.Unique))
181+
.ToDictionary(a => a.Attribute.Unique, a => trytb.Columns.Values.Where(b => b.Attribute.Unique == a.Attribute.Unique).ToList());
172182
tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb);
173183

174184
#region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类

FreeSql/MySql/MySqlDbFirst.cs

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ where a.table_schema in ({1}) and a.table_name in ({0})
239239
select
240240
concat(a.constraint_schema, '.', a.table_name) 'table_id',
241241
a.column_name,
242-
concat(a.constraint_schema, '/', a.table_name, '/', a.constraint_name) 'index_id',
242+
a.constraint_name 'index_id',
243243
1 'IsUnique',
244-
case when constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey',
244+
case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey',
245245
0 'IsClustered',
246246
0 'IsDesc'
247247
from information_schema.key_column_usage a
@@ -283,21 +283,21 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position
283283
}
284284
}
285285
foreach (string table_id in indexColumns.Keys) {
286-
foreach (var columns in indexColumns[table_id].Values)
287-
loc2[table_id].Indexes.Add(columns);
286+
foreach (var column in indexColumns[table_id])
287+
loc2[table_id].IndexesDict.Add(column.Key, column.Value);
288288
}
289289
foreach (string table_id in uniqueColumns.Keys) {
290-
foreach (var columns in uniqueColumns[table_id].Values) {
291-
columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
292-
loc2[table_id].Uniques.Add(columns);
290+
foreach (var column in uniqueColumns[table_id]) {
291+
column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
292+
loc2[table_id].UniquesDict.Add(column.Key, column.Value);
293293
}
294294
}
295295

296296
sql = string.Format(@"
297297
select
298298
concat(a.constraint_schema, '.', a.table_name) 'table_id',
299299
a.column_name,
300-
concat(a.constraint_schema, '/', a.constraint_name) 'FKId',
300+
a.constraint_name 'FKId',
301301
concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id',
302302
1 'IsForeignKey',
303303
a.referenced_column_name 'ref_column'
@@ -335,8 +335,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
335335
loc13.ReferencedColumns.Add(loc11);
336336
}
337337
foreach (var table_id in fkColumns.Keys)
338-
foreach (var fk in fkColumns[table_id].Values)
339-
loc2[table_id].Foreigns.Add(fk);
338+
foreach (var fk in fkColumns[table_id])
339+
loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value);
340340

341341
foreach (var table_id in loc3.Keys) {
342342
foreach (var loc5 in loc3[table_id].Values) {
@@ -346,8 +346,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
346346
}
347347
}
348348
foreach (var loc4 in loc2.Values) {
349-
if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) {
350-
foreach (var loc5 in loc4.Uniques[0]) {
349+
if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) {
350+
foreach (var loc5 in loc4.UniquesDict.First().Value) {
351351
loc5.IsPrimary = true;
352352
loc4.Primarys.Add(loc5);
353353
}
@@ -356,8 +356,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
356356
loc4.Columns.Sort((c1, c2) => {
357357
int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
358358
if (compare == 0) {
359-
bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null;
360-
bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null;
359+
bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any();
360+
bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any();
361361
compare = b2.CompareTo(b1);
362362
}
363363
if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
@@ -370,16 +370,6 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
370370
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
371371
return ret;
372372
});
373-
foreach(var loc4 in loc1) {
374-
var dicUniques = new Dictionary<string, List<DbColumnInfo>>();
375-
if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
376-
foreach(var loc5 in loc4.Uniques) {
377-
var dickey = string.Join(",", loc5.Select(a => a.Name));
378-
if (dicUniques.ContainsKey(dickey)) continue;
379-
dicUniques.Add(dickey, loc5);
380-
}
381-
loc4.Uniques = dicUniques.Values.ToList();
382-
}
383373

384374
loc2.Clear();
385375
loc3.Clear();

FreeSql/Oracle/OracleDbFirst.cs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ where a.owner in ({1}) and a.table_name in ({0})
251251
select
252252
a.owner || '.' || a.table_name,
253253
c.column_name,
254-
a.owner || '/' || a.table_name || '/' || c.constraint_name,
254+
c.constraint_name,
255255
case when a.constraint_type = 'U' then 1 else 0 end,
256256
case when a.constraint_type = 'P' then 1 else 0 end,
257257
0,
@@ -302,21 +302,21 @@ and a.owner in ({1}) and a.table_name in ({0})
302302
}
303303
}
304304
foreach (string table_id in indexColumns.Keys) {
305-
foreach (var columns in indexColumns[table_id].Values)
306-
loc2[table_id].Indexes.Add(columns);
305+
foreach (var column in indexColumns[table_id])
306+
loc2[table_id].IndexesDict.Add(column.Key, column.Value);
307307
}
308308
foreach (string table_id in uniqueColumns.Keys) {
309-
foreach (var columns in uniqueColumns[table_id].Values) {
310-
columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
311-
loc2[table_id].Uniques.Add(columns);
309+
foreach (var column in uniqueColumns[table_id]) {
310+
column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
311+
loc2[table_id].UniquesDict.Add(column.Key, column.Value);
312312
}
313313
}
314314

315315
sql = string.Format(@"
316316
select
317317
a.owner || '.' || a.table_name,
318318
c.column_name,
319-
a.owner || '/' || a.table_name || '/' || c.constraint_name,
319+
c.constraint_name,
320320
b.owner || '.' || b.table_name,
321321
1,
322322
d.column_name
@@ -379,8 +379,8 @@ and a.owner in ({1}) and a.table_name in ({0})
379379
loc13.ReferencedColumns.Add(loc11);
380380
}
381381
foreach (var table_id in fkColumns.Keys)
382-
foreach (var fk in fkColumns[table_id].Values)
383-
loc2[table_id].Foreigns.Add(fk);
382+
foreach (var fk in fkColumns[table_id])
383+
loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value);
384384

385385
foreach (var table_id in loc3.Keys) {
386386
foreach (var loc5 in loc3[table_id].Values) {
@@ -390,8 +390,8 @@ and a.owner in ({1}) and a.table_name in ({0})
390390
}
391391
}
392392
foreach (var loc4 in loc2.Values) {
393-
if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) {
394-
foreach (var loc5 in loc4.Uniques[0]) {
393+
if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) {
394+
foreach (var loc5 in loc4.UniquesDict.First().Value) {
395395
loc5.IsPrimary = true;
396396
loc4.Primarys.Add(loc5);
397397
}
@@ -400,8 +400,8 @@ and a.owner in ({1}) and a.table_name in ({0})
400400
loc4.Columns.Sort((c1, c2) => {
401401
int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
402402
if (compare == 0) {
403-
bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null;
404-
bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null;
403+
bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any();
404+
bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any();
405405
compare = b2.CompareTo(b1);
406406
}
407407
if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
@@ -414,16 +414,6 @@ and a.owner in ({1}) and a.table_name in ({0})
414414
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
415415
return ret;
416416
});
417-
foreach (var loc4 in loc1) {
418-
var dicUniques = new Dictionary<string, List<DbColumnInfo>>();
419-
if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
420-
foreach (var loc5 in loc4.Uniques) {
421-
var dickey = string.Join(",", loc5.Select(a => a.Name));
422-
if (dicUniques.ContainsKey(dickey)) continue;
423-
dicUniques.Add(dickey, loc5);
424-
}
425-
loc4.Uniques = dicUniques.Values.ToList();
426-
}
427417

428418
loc2.Clear();
429419
loc3.Clear();

0 commit comments

Comments
 (0)