11using FreeSql . DataAnnotations ;
22using System ;
3+ using System . Collections . Generic ;
4+ using System . Linq ;
35using System . Text ;
46using System . Threading ;
57
@@ -48,8 +50,6 @@ namespace FreeSql
4850 public static class SqlExt
4951 {
5052 public static ThreadLocal < ExpressionCallContext > expContext = new ThreadLocal < ExpressionCallContext > ( ) ;
51- static ThreadLocal < StringBuilder > expSb = new ThreadLocal < StringBuilder > ( ) ;
52- static ThreadLocal < bool > expSbIsOrderBy = new ThreadLocal < bool > ( ) ;
5353
5454 public static ISqlOver < long > Rank ( ) => Over < long > ( "RANK()" ) ;
5555 public static ISqlOver < long > DenseRank ( ) => Over < long > ( "DENSE_RANK()" ) ;
@@ -61,32 +61,34 @@ public static class SqlExt
6161 public static ISqlOver < long > RowNumber ( ) => Over < long > ( "ROW_NUMBER()" ) ;
6262
6363 #region .. over([partition by ..] order by ...)
64+ static ThreadLocal < StringBuilder > expOverSb = new ThreadLocal < StringBuilder > ( ) ;
65+ static ThreadLocal < bool > expOverSbIsOrderBy = new ThreadLocal < bool > ( ) ;
6466 static ISqlOver < TValue > Over < TValue > ( string sqlFunc )
6567 {
66- expSb . Value = new StringBuilder ( ) ;
67- expSbIsOrderBy . Value = false ;
68- expSb . Value . Append ( $ "{ sqlFunc } ") ;
68+ expOverSb . Value = new StringBuilder ( ) ;
69+ expOverSbIsOrderBy . Value = false ;
70+ expOverSb . Value . Append ( $ "{ sqlFunc } ") ;
6971 return null ;
7072 }
7173 public static ISqlOver < TValue > Over < TValue > ( this ISqlOver < TValue > that )
7274 {
73- expSb . Value . Append ( "OVER(" ) ;
75+ expOverSb . Value . Append ( "OVER(" ) ;
7476 return that ;
7577 }
7678 public static ISqlOver < TValue > PartitionBy < TValue > ( this ISqlOver < TValue > that , object column )
7779 {
78- expSb . Value . Append ( "PARTITION BY " ) . Append ( expContext . Value . ParsedContent [ "column" ] ) . Append ( "," ) ;
80+ expOverSb . Value . Append ( "PARTITION BY " ) . Append ( expContext . Value . ParsedContent [ "column" ] ) . Append ( "," ) ;
7981 return that ;
8082 }
8183 public static ISqlOver < TValue > OrderBy < TValue > ( this ISqlOver < TValue > that , object column ) => OrderBy ( that , false ) ;
8284 public static ISqlOver < TValue > OrderByDescending < TValue > ( this ISqlOver < TValue > that , object column ) => OrderBy ( that , true ) ;
8385 static ISqlOver < TValue > OrderBy < TValue > ( this ISqlOver < TValue > that , bool isDesc )
8486 {
85- var sb = expSb . Value ;
86- if ( expSbIsOrderBy . Value == false )
87+ var sb = expOverSb . Value ;
88+ if ( expOverSbIsOrderBy . Value == false )
8789 {
8890 sb . Append ( "ORDER BY " ) ;
89- expSbIsOrderBy . Value = true ;
91+ expOverSbIsOrderBy . Value = true ;
9092 }
9193 sb . Append ( expContext . Value . ParsedContent [ "column" ] ) ;
9294 if ( isDesc ) sb . Append ( " desc" ) ;
@@ -95,12 +97,48 @@ static ISqlOver<TValue> OrderBy<TValue>(this ISqlOver<TValue> that, bool isDesc)
9597 }
9698 public static TValue ToValue < TValue > ( this ISqlOver < TValue > that )
9799 {
98- var sb = expSb . Value . ToString ( ) . TrimEnd ( ',' ) ;
99- expSb . Value . Clear ( ) ;
100+ var sb = expOverSb . Value . ToString ( ) . TrimEnd ( ',' ) ;
101+ expOverSb . Value . Clear ( ) ;
100102 expContext . Value . Result = $ "{ sb } )";
101103 return default ;
102104 }
103105 public interface ISqlOver < TValue > { }
104106 #endregion
107+
108+ #region case when .. then .. when .. then .. end
109+ static ThreadLocal < List < StringBuilder > > expCaseWhenEndSb = new ThreadLocal < List < StringBuilder > > ( ) ;
110+ public static ICaseWhenEnd Case ( )
111+ {
112+ if ( expCaseWhenEndSb . Value == null ) expCaseWhenEndSb . Value = new List < StringBuilder > ( ) ;
113+ expCaseWhenEndSb . Value . Add ( new StringBuilder ( ) . Append ( "CASE " ) ) ;
114+ return null ;
115+ }
116+ public static ICaseWhenEnd < TValue > When < TValue > ( this ICaseWhenEnd that , bool test , TValue then )
117+ {
118+ expCaseWhenEndSb . Value . Last ( ) . Append ( "\r \n WHEN " ) . Append ( expContext . Value . ParsedContent [ "test" ] ) . Append ( " THEN " ) . Append ( expContext . Value . ParsedContent [ "then" ] ) ;
119+ return null ;
120+ }
121+ public static ICaseWhenEnd < TValue > When < TValue > ( this ICaseWhenEnd < TValue > that , bool test , TValue then )
122+ {
123+ expCaseWhenEndSb . Value . Last ( ) . Append ( "\r \n WHEN " ) . Append ( expContext . Value . ParsedContent [ "test" ] ) . Append ( " THEN " ) . Append ( expContext . Value . ParsedContent [ "then" ] ) ;
124+ return null ;
125+ }
126+ public static ICaseWhenEnd < TValue > Else < TValue > ( this ICaseWhenEnd < TValue > that , TValue then )
127+ {
128+ expCaseWhenEndSb . Value . Last ( ) . Append ( "\r \n ELSE " ) . Append ( expContext . Value . ParsedContent [ "then" ] ) ;
129+ return null ;
130+ }
131+ public static TValue End < TValue > ( this ICaseWhenEnd < TValue > that )
132+ {
133+ var sb = expCaseWhenEndSb . Value ;
134+ var sql = sb . Last ( ) . Append ( "\r \n END" ) . ToString ( ) ;
135+ sb . Last ( ) . Clear ( ) ;
136+ sb . RemoveAt ( sb . Count - 1 ) ;
137+ expContext . Value . Result = sql ;
138+ return default ;
139+ }
140+ public interface ICaseWhenEnd { }
141+ public interface ICaseWhenEnd < TValue > { }
142+ #endregion
105143 }
106144}
0 commit comments