@ -1,4 +1,4 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					 /* 2021.11.07  */  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					 /* 2021.12.01  */  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  Apewer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  System ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -9,6 +9,7 @@ using System.Text; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  static  Apewer . Source . SourceUtility ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  System.Data.SqlClient ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  System.IO ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#if NETFRAMEWORK
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					using  System.Data.Sql ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -113,6 +114,24 @@ namespace Apewer.Source 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>改变</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <param name="store"></param>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <returns></returns>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  string  Change ( string  store )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( store . IsEmpty ( ) )  return  "未指定数据名称。" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            var  connect  =  Connect ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( connect . NotEmpty ( ) )  return  connect ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            try  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                _d b . ChangeDatabase ( store ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  null ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            catch  ( Exception  ex )  {  return  ex . Message ( ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>关闭连接,并释放对象所占用的系统资源。</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  void  Close ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -249,10 +268,13 @@ namespace Apewer.Source 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>执行。</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  IExecute  Execute ( string  sql )  = >  Execute ( sql ,  null ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  IExecute  Execute ( string  sql )  = >  Execute ( sql ,  null ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>执行单条 Transact-SQL 语句,并加入参数。</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  IExecute  Execute ( string  sql ,  IEnumerable < IDataParameter >  parameters )  = >  Execute ( sql ,  parameters ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>执行单条 Transact-SQL 语句,并加入参数。</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  IExecute  Execute ( string  sql ,  IEnumerable < IDataParameter >  parameters )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        IExecute  Execute ( string  sql ,  IEnumerable < IDataParameter >  parameters ,  bool  requireTransaction )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( TextUtility . IsBlank ( sql ) )  return  Example . InvalidExecuteStatement ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -260,13 +282,13 @@ namespace Apewer.Source 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( connected . NotEmpty ( ) )  return  new  Execute ( false ,  connected ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            var  inTransaction  =  _ transaction  ! =  null ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! inTransaction )  Begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( requireTransaction  & &  ! inTransaction )  Begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            try  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                using  ( var  command  =  new  SqlCommand ( ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    command . Connection  =  _d b ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    command . Transaction  =  ( SqlTransaction ) _ transaction ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( requireTransaction )  command . Transaction  =  ( SqlTransaction ) _ transaction ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    command . CommandTimeout  =  _ timeout . Execute ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    command . CommandText  =  sql ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( parameters  ! =  null )  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -277,14 +299,14 @@ namespace Apewer.Source 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    var  rows  =  command . ExecuteNonQuery ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( ! inTransaction )  Commit ( ) ;  // todo 此处应该检查事务提交产生的错误。
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( requireTransaction  & &  ! inTransaction )  Commit ( ) ;  // todo 此处应该检查事务提交产生的错误。
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  new  Execute ( true ,  rows ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            catch  ( Exception  exception )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                Logger . Error ( nameof ( SqlClient ) ,  "Execute" ,  exception ,  sql ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! inTransaction )  Rollback ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( requireTransaction  & &  ! inTransaction )  Rollback ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  new  Execute ( exception ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -355,6 +377,62 @@ namespace Apewer.Source 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  list . ToArray ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <summary>创建数据库,返回错误信息。</summary>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <param name="storeName">数据库名称。</param>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        /// <returns>成功时候返回 NULL 值,失败时返回错误信息。</returns>
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        public  string  CreateStore ( string  storeName )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            var  store  =  storeName . Escape ( ) . ToTrim ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( store . IsEmpty ( ) )  return  "创建失败:未指定数据库名称。" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ConnectionString . IsEmpty ( ) )  return  "创建失败:未指定数据库连接方式。" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            using  ( var  source  =  new  SqlClient ( ConnectionString ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  connect  =  source . Connect ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( connect . NotEmpty ( ) )  return  "创建失败:"  +  connect ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  schema  =  source . SimpleCell ( "select default_schema_name from sys.database_principals where type = 'S' and name=user_name()" ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( schema . IsEmpty ( ) )  return  "创建失败:无法获取默认模式名称。" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  refPath  =  source . SimpleCell ( @"select f.physical_name path from sys.filegroups g left join sys.database_files f on f.data_space_id = g.data_space_id where g.name = 'PRIMARY' and g.type = 'FG' and g.is_default = 1 and g.filegroup_guid is null" ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( refPath . IsEmpty ( ) )  return  "创建失败:无法获取文件路径。" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  dir  =  Path . GetDirectoryName ( refPath ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  mdfPath  =  Path . Combine ( dir ,  store )  +  ".mdf" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  ldfPath  =  Path . Combine ( dir ,  store )  +  "_log.ldf" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // 创建库。
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  sql1  =  $ @ "
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					CREATE  DATABASE  [ { store } ]  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					ON  PRIMARY  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					(  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    NAME  =  N ' { store } ' ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    FILENAME  =  N ' { mdfPath } ' ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SIZE  =  8 1 9 2 KB ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    MAXSIZE  =  UNLIMITED ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    FILEGROWTH  =  4 MB  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					)  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					LOG  ON  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					(  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    NAME  =  N ' { store } _l og ' ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    FILENAME  =  N ' { ldfPath } ' ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SIZE  =  8 MB ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    MAXSIZE  =  1 0 2 4 MB ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    FILEGROWTH  =  4 MB  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					)  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					COLLATE  Chinese_PRC_CI_AS  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					";
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  create  =  source . Execute ( sql1 ,  null ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! create . Success )  return  TextUtility . Merge ( "创建失败:" ,  create . Message ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // 设计兼容性级别。
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                var  sql2  =  $"ALTER DATABASE [{store}] SET COMPATIBILITY_LEVEL = 0" ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                source . Execute ( sql2 ,  null ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  null ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        static  string  XType ( int  xtype )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            switch  ( xtype )