| 
						
						
						
					 | 
					@ -1,4 +1,4 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					/* 2021.12.01 */ | 
					 | 
					 | 
					/* 2021.12.07 */ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					using Apewer; | 
					 | 
					 | 
					using Apewer; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					using System; | 
					 | 
					 | 
					using System; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -311,6 +311,39 @@ namespace Apewer.Source | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <summary>批量插入,必须在 DataTable 中指定表名,或指定 tableName 参数。</summary>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="ArgumentNullException"></exception>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="ArgumentException"></exception>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        public void BulkCopy(DataTable table, string tableName = null) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // 检查 table 参数。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (table == null) throw new ArgumentNullException(nameof(table)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (table.Rows.Count < 1) return; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // 检查 tableName 参数。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (tableName.IsEmpty()) tableName = table.TableName; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (tableName.IsEmpty()) throw new ArgumentException("未指定表名。"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // 连接数据库。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var connect = Connect(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (connect.NotEmpty()) throw new Exception(connect); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // 批量插入。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var bc = null as SqlBulkCopy; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            try | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                bc = new SqlBulkCopy(_db); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                bc.DestinationTableName = tableName; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                bc.BatchSize = table.Rows.Count; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                bc.WriteToServer(table); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            catch (Exception ex) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                try { bc.Close(); } catch { } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                throw ex; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        #endregion
 | 
					 | 
					 | 
					        #endregion
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        #region ORM
 | 
					 | 
					 | 
					        #region ORM
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -566,11 +599,16 @@ COLLATE Chinese_PRC_CI_AS | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    if (structure.Independent && column.Independent) continue; | 
					 | 
					 | 
					                    if (structure.Independent && column.Independent) continue; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    var type = Declaration(column); | 
					 | 
					 | 
					                    var type = Declaration(column); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    if (!column.Independent && column.Property.Name == "Key") type = type + " primary key"; | 
					 | 
					 | 
					                    if (!column.Independent) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        if (column.PrimaryKey) type = type + " primary key"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        if (column.Incremental) type += " identity"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    if (string.IsNullOrEmpty(type)) return TextUtility.Merge("类型 ", column.Type.ToString(), " 不受支持。"); | 
					 | 
					 | 
					                    if (string.IsNullOrEmpty(type)) return TextUtility.Merge("类型 ", column.Type.ToString(), " 不受支持。"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    sqlcolumns.Add(type); | 
					 | 
					 | 
					                    sqlcolumns.Add(type); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                } | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (sqlcolumns.Count < 1) return $"无法对类型 {model.FullName} 创建表:没有定义任何字段。"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                var sql = TextUtility.Merge("create table [", structure.Name, "](", string.Join(", ", sqlcolumns.ToArray()), "); "); | 
					 | 
					 | 
					                var sql = TextUtility.Merge("create table [", structure.Name, "](", string.Join(", ", sqlcolumns.ToArray()), "); "); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                var execute = Execute(sql); | 
					 | 
					 | 
					                var execute = Execute(sql); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                if (execute.Success) return TextUtility.Empty; | 
					 | 
					 | 
					                if (execute.Success) return TextUtility.Empty; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -589,7 +627,15 @@ COLLATE Chinese_PRC_CI_AS | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) table = structure.Name; | 
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) table = structure.Name; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) return "表名称无效。"; | 
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) return "表名称无效。"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            var ps = structure.CreateParameters(record, Parameter); | 
					 | 
					 | 
					            // 排除字段。
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var excluded = new List<string>(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            foreach (var ca in structure.Columns) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                // 排除不使用 ORM 的属性。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (ca.Independent || ca.Incremental) excluded.Add(ca.Field); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var ps = structure.CreateParameters(record, Parameter, excluded); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            var psc = ps.Length; | 
					 | 
					 | 
					            var psc = ps.Length; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (psc < 1) return "数据模型不包含字段。"; | 
					 | 
					 | 
					            if (psc < 1) return "数据模型不包含字段。"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -625,7 +671,16 @@ COLLATE Chinese_PRC_CI_AS | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) table = structure.Name; | 
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) table = structure.Name; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) return "表名称无效。"; | 
					 | 
					 | 
					            if (string.IsNullOrEmpty(table)) return "表名称无效。"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            var ps = structure.CreateParameters(record, Parameter, "_key"); | 
					 | 
					 | 
					            // 排除字段。
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var excluded = new List<string>(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (structure.Key != null) excluded.Add(structure.Key.Field); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            foreach (var ca in structure.Columns) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                // 排除不使用 ORM 的属性、自增属性和主键属性。
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (ca.Independent || ca.Incremental || ca.PrimaryKey) excluded.Add(ca.Field); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var ps = structure.CreateParameters(record, Parameter, excluded); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            var psc = ps.Length; | 
					 | 
					 | 
					            var psc = ps.Length; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (psc < 1) return "数据模型不包含字段。"; | 
					 | 
					 | 
					            if (psc < 1) return "数据模型不包含字段。"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -756,6 +811,9 @@ COLLATE Chinese_PRC_CI_AS | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            var vtype = SqlDbType.BigInt; | 
					 | 
					 | 
					            var vtype = SqlDbType.BigInt; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            switch (type) | 
					 | 
					 | 
					            switch (type) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            { | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                case ColumnType.Boolean: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    vtype = SqlDbType.Bit; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    break; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                case ColumnType.Bytes: | 
					 | 
					 | 
					                case ColumnType.Bytes: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    vtype = SqlDbType.Image; | 
					 | 
					 | 
					                    vtype = SqlDbType.Image; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    break; | 
					 | 
					 | 
					                    break; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -853,6 +911,9 @@ COLLATE Chinese_PRC_CI_AS | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            var length = Math.Max(0, vcolumn.Length); | 
					 | 
					 | 
					            var length = Math.Max(0, vcolumn.Length); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            switch (vcolumn.Type) | 
					 | 
					 | 
					            switch (vcolumn.Type) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            { | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                case ColumnType.Boolean: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    type = "bit"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    break; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                case ColumnType.Integer: | 
					 | 
					 | 
					                case ColumnType.Integer: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    type = "bigint"; | 
					 | 
					 | 
					                    type = "bigint"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    break; | 
					 | 
					 | 
					                    break; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |