From dae8eb7a67e1748f3374cd707288fc8e97db9fae Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 11 Mar 2019 19:00:44 +0800 Subject: [PATCH] =?UTF-8?q?v0.3.12=20=E5=A2=9E=E5=8A=A0=20ICodeFirst.IsCon?= =?UTF-8?q?figEntityFromDbFirst=EF=BC=8C=E8=8B=A5=E6=97=A0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=AE=9E=E4=BD=93=E7=B1=BB=E4=B8=BB=E9=94=AE=E3=80=81?= =?UTF-8?q?=E8=87=AA=E5=A2=9E=EF=BC=8C=E5=8F=AF=E4=BB=8E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=AF=BC=E5=85=A5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/net461_console_01/Program.cs | 8 +++-- .../net461_console_01.csproj | 16 ++++++---- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSqlBuilder.cs | 11 +++++++ FreeSql/Interface/ICodeFirst.cs | 4 +++ FreeSql/Internal/CommonUtils.cs | 3 ++ FreeSql/Internal/UtilsExpressionTree.cs | 32 +++++++++++++++++-- FreeSql/MySql/MySqlCodeFirst.cs | 1 + FreeSql/MySql/MySqlDbFirst.cs | 10 ++++-- FreeSql/Oracle/OracleCodeFirst.cs | 1 + FreeSql/Oracle/OracleProvider.cs | 2 +- FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs | 1 + FreeSql/SqlServer/SqlServerCodeFirst.cs | 1 + FreeSql/Sqlite/SqliteCodeFirst.cs | 1 + FreeSql/Sqlite/SqliteProvider.cs | 2 +- readme.md | 1 + 17 files changed, 81 insertions(+), 17 deletions(-) diff --git a/Examples/net461_console_01/Program.cs b/Examples/net461_console_01/Program.cs index 1d221945..f43ca833 100644 --- a/Examples/net461_console_01/Program.cs +++ b/Examples/net461_console_01/Program.cs @@ -11,12 +11,14 @@ namespace net46_console_01 { var orm = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") .UseAutoSyncStructure(true) + .UseConfigEntityFromDbFirst(true) .Build(); - var repos = orm.GetGuidRepository(); + var repos = orm.GetGuidRepository(); - var item = repos.Insert(new Song()); + var item = repos.Insert(new Song22()); Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); item.Title = "xxx"; @@ -31,7 +33,7 @@ namespace net46_console_01 { } } - public class Song { + public class Song22 { public Guid Id { get; set; } public string Title { get; set; } diff --git a/Examples/net461_console_01/net461_console_01.csproj b/Examples/net461_console_01/net461_console_01.csproj index d83e08e1..0b542f52 100644 --- a/Examples/net461_console_01/net461_console_01.csproj +++ b/Examples/net461_console_01/net461_console_01.csproj @@ -39,12 +39,6 @@ ..\..\packages\CS-Script.Core.1.0.6\lib\netstandard2.0\CSScriptLib.dll - - ..\..\packages\FreeSql.0.1.11\lib\netstandard2.0\FreeSql.dll - - - ..\..\packages\FreeSql.Repository.0.1.11\lib\netstandard2.0\FreeSql.Repository.dll - ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll @@ -269,6 +263,16 @@ + + + {ac47670e-90bb-4502-9965-0739bdf6fe2e} + FreeSql.Repository + + + {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} + FreeSql + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4cb0d516..95844bb3 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.11 + 0.3.12 YeXiangQin FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 https://github.com/2881099/FreeSql diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f402bfdc..3c35d0aa 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.11 + 0.3.12 true YeXiangQin 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 04765984..a484d42e 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -15,6 +15,7 @@ namespace FreeSql { bool _isAutoSyncStructure = false; bool _isSyncStructureToLower = false; bool _isSyncStructureToUpper = false; + bool _isConfigEntityFromDbFirst = false; bool _isLazyLoading = false; Action _aopCommandExecuting = null; Action _aopCommandExecuted = null; @@ -86,6 +87,15 @@ namespace FreeSql { return this; } /// + /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// + /// + /// + public FreeSqlBuilder UseConfigEntityFromDbFirst(bool value) { + _isConfigEntityFromDbFirst = value; + return this; + } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// /// @@ -120,6 +130,7 @@ namespace FreeSql { ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; + ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; ret.CodeFirst.IsLazyLoading = _isLazyLoading; var ado = ret.Ado as Internal.CommonProvider.AdoProvider; ado.AopCommandExecuting += _aopCommandExecuting; diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 8683eaf4..2545f301 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -18,6 +18,10 @@ namespace FreeSql { /// bool IsSyncStructureToUpper { get; set; } /// + /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// + bool IsConfigEntityFromDbFirst { get; set; } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// bool IsLazyLoading { get; set; } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 6406dfd0..df209a70 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; using FreeSql.Internal.Model; using System; using System.Collections; @@ -27,6 +28,8 @@ namespace FreeSql.Internal { internal IFreeSql _orm { get; set; } internal ICodeFirst CodeFirst => _orm.CodeFirst; internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this); + internal List dbTables { get; set; } + internal object dbTablesLock = new object(); public CommonUtils(IFreeSql orm) { _orm = orm; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f4246b50..0f6db3fb 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -113,8 +113,8 @@ namespace FreeSql.Internal { } trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); if (trytb.Primarys.Any() == false) { - var identcols = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); - if (identcols != null) trytb.Primarys = new[] { identcols }; + var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); + if (identcol != null) trytb.Primarys = new[] { identcol }; if (trytb.Primarys.Any() == false) { trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); if (trytb.Primarys.Any() == false) { @@ -127,6 +127,34 @@ namespace FreeSql.Internal { foreach (var col in trytb.Primarys) col.Attribute.IsPrimary = true; } + //从数据库查找主键、自增 + if (common.CodeFirst.IsConfigEntityFromDbFirst) { + try { + if (common._orm.DbFirst != null) { + if (common.dbTables == null) + lock (common.dbTablesLock) + if (common.dbTables == null) + common.dbTables = common._orm.DbFirst.GetTablesByDatabase(); + + var finddbtbs = common.dbTables.Where(a => string.Compare(a.Name, trytb.CsName, true) == 0 || string.Compare(a.Name, trytb.DbName, true) == 0); + foreach (var dbtb in finddbtbs) { + foreach (var dbident in dbtb.Identitys) { + if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.CsType == dbident.CsType || + trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.CsType == dbident.CsType) { + trycol.Attribute.IsIdentity = true; + } + } + foreach (var dbpk in dbtb.Primarys) { + if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.CsType == dbpk.CsType || + trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.CsType == dbpk.CsType) { + trycol.Attribute.IsPrimary = true; + } + } + } + } + } catch { } + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + } tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region virtual 属性延时加载,动态产生新的重写类 diff --git a/FreeSql/MySql/MySqlCodeFirst.cs b/FreeSql/MySql/MySqlCodeFirst.cs index 1355fe9a..db3ce210 100644 --- a/FreeSql/MySql/MySqlCodeFirst.cs +++ b/FreeSql/MySql/MySqlCodeFirst.cs @@ -26,6 +26,7 @@ namespace FreeSql.MySql { public bool IsAutoSyncStructure { get; set; } = true; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; public bool IsLazyLoading { get; set; } = false; static object _dicCsToDbLock = new object(); diff --git a/FreeSql/MySql/MySqlDbFirst.cs b/FreeSql/MySql/MySqlDbFirst.cs index d9cc5442..69163802 100644 --- a/FreeSql/MySql/MySqlDbFirst.cs +++ b/FreeSql/MySql/MySqlDbFirst.cs @@ -136,12 +136,18 @@ namespace FreeSql.MySql { return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } - public List GetTablesByDatabase(params string[] database) { + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); + var database = database2?.ToArray(); - if (database == null || database.Any() == false) return loc1; + if (database == null || database.Any() == false) { + using (var conn = _orm.Ado.MasterPool.Get()) { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + database = new[] { conn.Value.Database }; + } + } var databaseIn = string.Join(",", database.Select(a => "{0}".FormatMySql(a))); var sql = string.Format(@" select diff --git a/FreeSql/Oracle/OracleCodeFirst.cs b/FreeSql/Oracle/OracleCodeFirst.cs index 495de20f..ea20540b 100644 --- a/FreeSql/Oracle/OracleCodeFirst.cs +++ b/FreeSql/Oracle/OracleCodeFirst.cs @@ -27,6 +27,7 @@ namespace FreeSql.Oracle { public bool IsQuoteSqlName { get; set; } = true; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; public bool IsLazyLoading { get; set; } = false; static object _dicCsToDbLock = new object(); diff --git a/FreeSql/Oracle/OracleProvider.cs b/FreeSql/Oracle/OracleProvider.cs index 47c14b43..bfee74d7 100644 --- a/FreeSql/Oracle/OracleProvider.cs +++ b/FreeSql/Oracle/OracleProvider.cs @@ -25,7 +25,7 @@ namespace FreeSql.Oracle { public IAdo Ado { get; } public ICache Cache { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get { throw new NotImplementedException(); } } + public IDbFirst DbFirst => null; public OracleProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Oracle"); diff --git a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs index b754bbc7..c6b402b1 100644 --- a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs +++ b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs @@ -31,6 +31,7 @@ namespace FreeSql.PostgreSQL { public bool IsAutoSyncStructure { get; set; } = true; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; public bool IsLazyLoading { get; set; } = false; static object _dicCsToDbLock = new object(); diff --git a/FreeSql/SqlServer/SqlServerCodeFirst.cs b/FreeSql/SqlServer/SqlServerCodeFirst.cs index 2186c226..fa4b47d4 100644 --- a/FreeSql/SqlServer/SqlServerCodeFirst.cs +++ b/FreeSql/SqlServer/SqlServerCodeFirst.cs @@ -25,6 +25,7 @@ namespace FreeSql.SqlServer { public bool IsAutoSyncStructure { get; set; } = true; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; public bool IsLazyLoading { get; set; } = false; static object _dicCsToDbLock = new object(); diff --git a/FreeSql/Sqlite/SqliteCodeFirst.cs b/FreeSql/Sqlite/SqliteCodeFirst.cs index 767a6464..40dee30d 100644 --- a/FreeSql/Sqlite/SqliteCodeFirst.cs +++ b/FreeSql/Sqlite/SqliteCodeFirst.cs @@ -25,6 +25,7 @@ namespace FreeSql.Sqlite { public bool IsAutoSyncStructure { get; set; } = true; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; public bool IsLazyLoading { get; set; } = false; static object _dicCsToDbLock = new object(); diff --git a/FreeSql/Sqlite/SqliteProvider.cs b/FreeSql/Sqlite/SqliteProvider.cs index a269102f..1b7e8c5c 100644 --- a/FreeSql/Sqlite/SqliteProvider.cs +++ b/FreeSql/Sqlite/SqliteProvider.cs @@ -25,7 +25,7 @@ namespace FreeSql.Sqlite { public IAdo Ado { get; } public ICache Cache { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get { throw new NotImplementedException(); } } + public IDbFirst DbFirst => null; public SqliteProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Sqlite"); diff --git a/readme.md b/readme.md index 1c6431b2..0a16e8fc 100644 --- a/readme.md +++ b/readme.md @@ -40,6 +40,7 @@ IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) //自动同步实体结构到数据库 .UseSyncStructureToLower(true) //转小写同步结构 .UseSyncStructureToUpper(true) //转大写同步结构 + .UseConfigEntityFromDbFirst(true) //若无配置实体类主键、自增,可从数据库导入 .UseLazyLoading(true) //延时加载导航属性对象,导航属性需要声明 virtual .Build();