@@ -1,4 +1,5 @@
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 using  FreeSql.DataAnnotations ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				using  FreeSql.Extensions.ZeroEntity.Models ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				using  FreeSql.Internal ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				using  FreeSql.Internal.CommonProvider ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				using  FreeSql.Internal.Model ; 
 
			
		 
		
	
	
		
			
				
					
					
						
					 
				
			
			 
			 
			
				@@ -64,23 +65,75 @@ ManyToMany 级联删除中间表(注意不删除外部根)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        internal  DbTransaction  _transaction ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        internal  int  _commandTimeout ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        internal  List < ZeroTableInfo >  _tables ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						public  ZeroDbContext ( IFreeSql  orm ,  TableDescriptor [ ]  schemas ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// 创建新的ZeroDbCotext实例 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// </summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <param name="orm">IfreeSql 对象</param> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <param name="schemas">动态表结构描述</param> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <param name="syncStructure">是否强制同步表结构</param> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <exception cref="SchemaValidationResult"> Schema 未验证通过时抛出验证异常</exception> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  ZeroDbContext ( IFreeSql  orm ,  TableDescriptor [ ]  schemas ,  bool  syncStructure  =  false ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            _orm  =  orm ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							 _tables  =  ValidateSchemaToInfo ( orm ,  schemas ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  (  orm . CodeFirst . IsAutoSyncStructure ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				             _tables  =  ValidateSchemaToInfoInternal  ( orm ,  schemas ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( syncStructure  | |   orm . CodeFirst . IsAutoSyncStructure ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                foreach  ( var  table  in  _tables ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    orm . CodeFirst . SyncStructure ( table ,  table . DbName ,  false ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// 初始化一个 ZeroDbContext 对象,  暂不指定任何Schema 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// </summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <param name="orm"></param> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  ZeroDbContext ( IFreeSql  orm ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            _orm  =  orm ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            _tables  =  new  List < ZeroTableInfo > ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  SchemaValidationResult  ValidateSchema ( IEnumerable < TableDescriptor >  schemas ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            try 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                ValidateSchemaToInfoInternal ( _orm ,  schemas ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            catch  ( SchemaValidationException  ex ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                return  new  SchemaValidationResult ( ex . Message ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            return  SchemaValidationResult . SuccessedResult ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  TableInfo  GetTableInfo ( string  name )  = >  _tables . Where ( a  = >  a . CsName  = =  name ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						public  void  SyncStructure ( string  name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  void  SyncStructure ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            foreach  ( var  table  in  _tables ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                _orm . CodeFirst . SyncStructure ( table ,  table . DbName ,  false ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  void  SyncStructure ( TableDescriptor [ ]  schemas ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            _tables  =  ValidateSchemaToInfoInternal ( _orm ,  schemas ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            foreach  ( var  table  in  _tables ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                _orm . CodeFirst . SyncStructure ( table ,  table . DbName ,  false ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// 同步指定表结构 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// </summary> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /// <param name="name"></param> 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        public  void  SyncTableStructure ( string  name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            var  table  =  GetTableInfo ( name ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            _orm . CodeFirst . SyncStructure ( table ,  table . DbName ,  false ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						static  List < ZeroTableInfo >  ValidateSchemaToInfo ( IFreeSql  orm ,  IEnumerable < TableDescriptor >  schemas ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        static  List < ZeroTableInfo >  ValidateSchemaToInfoInternal ( IFreeSql  orm ,  IEnumerable < TableDescriptor >  schemas ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            var  common  =  ( orm . Ado  as  AdoProvider ) . _util ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            var  tables  =  new  List < ZeroTableInfo > ( ) ; 
 
			
		 
		
	
	
		
			
				
					
					
						
					 
				
			
			 
			 
			
				@@ -141,7 +194,8 @@ ManyToMany 级联删除中间表(注意不删除外部根)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    nav . NavigateKey  =  dtdnav . Name ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    nav . Table  =  tab ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    nav . RefTable  =  tables . Where ( a  = >  a . CsName  = =  dtdnav . RelTable ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									if  ( nav . RefTable  = =  null )  throw  new  Exception ( $"{error}未定义“{dtdnav.RelTable}”" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if  ( nav . RefTable  = =  null )  throw  new  SchemaValidationException ( $"{error}未定义“{dtdnav.RelTable}”" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    switch  ( dtdnav . Type ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    { 
 
			
		 
		
	
	
		
			
				
					
					
						
					 
				
			
			 
			 
			
				@@ -173,22 +227,22 @@ ManyToMany 级联删除中间表(注意不删除外部根)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            nav . RefType  =  TableRefType . ManyToMany ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midtab  =  tables . Where ( a  = >  a . CsName  = =  dtdnav . ManyToMany ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            nav . RefMiddleTable  =  midtab ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( nav . RefMiddleTable  = =  null )  throw  new  Exception ( $"{error}ManyToMany未定义“{dtdnav.ManyToMany}”" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( nav . RefMiddleTable  = =  null )  throw  new  SchemaValidation Exception( $"{error}ManyToMany未定义“{dtdnav.ManyToMany}”" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midtabRaw  =  schemas . Where ( a  = >  a . Name  = =  midtab . CsName ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midTabNav1  =  midtabRaw . Navigates . Where ( a  = >  a . Type  = =  TableDescriptor . NavigateType . ManyToOne  & &  a . RelTable  = =  nav . Table . CsName ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav1  = =  null )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.Table.CsName}”形成 ManyToOne 关联" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav1  = =  null )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.Table.CsName}”形成 ManyToOne 关联" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midTabNav1Columns  =  midTabNav1 . Bind . Split ( ',' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                    . Select ( a  = >  midtab . ColumnsByCs . TryGetValue ( a . Trim ( ) ,  out  var  refcol )  ?  refcol . CsName  :  "" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                    . Where ( a  = >  string . IsNullOrWhiteSpace ( a )  = =  false ) . ToArray ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midTabNav2  =  midtabRaw . Navigates . Where ( a  = >  a . Type  = =  TableDescriptor . NavigateType . ManyToOne  & &  a . RelTable  = =  nav . RefTable . CsName ) . FirstOrDefault ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav2  = =  null )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.RefTable.CsName}”形成 ManyToOne 关联" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav2  = =  null )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”没有与表“{nav.RefTable.CsName}”形成 ManyToOne 关联" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            var  midTabNav2Columns  =  midTabNav2 . Bind . Split ( ',' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                    . Select ( a  = >  midtab . ColumnsByCs . TryGetValue ( a . Trim ( ) ,  out  var  refcol )  ?  refcol . CsName  :  "" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                    . Where ( a  = >  string . IsNullOrWhiteSpace ( a )  = =  false ) . ToArray ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav1Columns . Length  ! =  nav . Table . Primarys . Length )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav1Columns . Where ( ( a ,  idx )  = >  midtab . ColumnsByCs [ a ] . CsType  ! =  nav . Table . Primarys [ idx ] . CsType ) . Any ( ) )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的类型不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav2Columns . Length  ! =  nav . RefTable . Primarys . Length )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( midTabNav2Columns . Where ( ( a ,  idx )  = >  midtab . ColumnsByCs [ a ] . CsType  ! =  nav . RefTable . Primarys [ idx ] . CsType ) . Any ( ) )  throw  new  Exception ( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的类型不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav1Columns . Length  ! =  nav . Table . Primarys . Length )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav1Columns . Where ( ( a ,  idx )  = >  midtab . ColumnsByCs [ a ] . CsType  ! =  nav . Table . Primarys [ idx ] . CsType ) . Any ( ) )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”关联字段的类型不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav2Columns . Length  ! =  nav . RefTable . Primarys . Length )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( midTabNav2Columns . Where ( ( a ,  idx )  = >  midtab . ColumnsByCs [ a ] . CsType  ! =  nav . RefTable . Primarys [ idx ] . CsType ) . Any ( ) )  throw  new  SchemaValidation Exception( $"{error}ManyToMany中间表“{dtdnav.ManyToMany}”与表“{nav.RefTable.CsName}”关联字段的类型不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            nav . Columns . AddRange ( nav . Table . Primarys . Select ( a  = >  a . CsName ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            nav . MiddleColumns . AddRange ( midTabNav1Columns ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            nav . MiddleColumns . AddRange ( midTabNav2Columns ) ; 
 
			
		 
		
	
	
		
			
				
					
					
						
					 
				
			
			 
			 
			
				@@ -200,8 +254,8 @@ ManyToMany 级联删除中间表(注意不删除外部根)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        case  TableDescriptor . NavigateType . OneToOne : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        case  TableDescriptor . NavigateType . ManyToOne : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        case  TableDescriptor . NavigateType . OneToMany : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( nav . Columns . Any ( )  = =  false  | |  nav . Columns . Count  ! =  nav . RefColumns . Count )  throw  new  Exception ( $"{error}与表“{dtdnav.RelTable}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											 if  ( nav . Columns . Where ( ( a ,  idx )  = >  nav . Table . ColumnsByCs [ a ] . CsType  ! =  nav . RefTable . ColumnsByCs [ nav . RefColumns [ idx ] ] . CsType ) . Any ( ) )  throw  new  Exception ( $"{error}与表“{dtdnav.RelTable}”关联字段的类型不匹配" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( nav . Columns . Any ( )  = =  false  | |  nav . Columns . Count  ! =  nav . RefColumns . Count )  throw  new  SchemaValidation Exception( $"{error}与表“{dtdnav.RelTable}”关联字段的数目不相等" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             if  ( nav . Columns . Where ( ( a ,  idx )  = >  nav . Table . ColumnsByCs [ a ] . CsType  ! =  nav . RefTable . ColumnsByCs [ nav . RefColumns [ idx ] ] . CsType ) . Any ( ) )  throw  new  SchemaValidation Exception( $"{error}与表“{dtdnav.RelTable}”关联字段的类型不匹配" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    tab . Navigates . Add ( dtdnav . Name ,  nav ) ;