我正在設計一個用於編寫SQL的流暢API。請記住,我的目標之一是讓API不建議無法在該鏈中調用的函數。例如,如果您剛剛在select子句中定義了一個字段,那麼在您調用From first之前,您無法調用Where。一個簡單的查詢如下所示:Fluent API中的遞歸
string sql = SelectBuilder.Create()
.Select()
.Fld("field1")
.From("table1")
.Where()
.Whr("field1 > field2")
.Whr("CURRENT_TIMESTAMP > field3")
.Build()
.SQL;
我的問題伴隨着SQL代碼中的遞歸。假設你想有一個字段包含另一個SQL語句,如下所示:
string sql = SelectBuilder.Create()
.Select()
.Fld("field1")
.SQLFld()
.Select
.Count("field6")
.From("other table")
.EndSQLFld()
.FLd("field2")
.From("table1")
.Where()
.Whr("field1 > field2")
.Whr("CURRENT_TIMESTAMP > field3")
.Build()
.SQL;
我正在使用方法鏈來構建我的流利API。它在很多方面都是遍佈許多代表每個狀態的類的狀態機。爲了添加這個功能,我需要複製我已經擁有的每個狀態,並將它們包裝在兩個SQLFld和EndSQLFld狀態中。我還需要另一個副本,如果你是更低級別的,並且將SQL語句嵌入到已經嵌入的SQL語句的字段中。這會延續到無窮大,所以對於無限深的嵌入式SQL查詢,我需要無限數量的類來表示無限狀態。
我想過編寫一個SelectBuilder查詢,它被帶到了Build方法的地方,然後將該SelectBuilder嵌入到另一個SelectBuilder中,並修復了我的無窮大問題,但它不是很優雅,這就是這個點API。
我也可以拋出這樣的想法,即API只在合適的時候提供函數,但我真的很討厭這麼做。我覺得這樣可以幫助你最好地發現如何使用API。在許多流利的API中,調用哪個順序並不重要,但我希望API儘可能接近實際的SQL語句並強制執行其語法。
任何人有任何想法如何解決這個問題?
我還以爲你在談論遞歸的CTE。請注意,子查詢可以包含對外部環境的引用(實際上這是_normal_情況)。子查詢也可以用作表引用('FROM' /'JOIN'子句)和'WHERE'子句。我希望你不只是將字符串連接在一起,因爲人們可能會認爲這是SQL注入證明(至少,你需要提供一個可變參數化方法)。當然,C#已經有了Linq-to-SQL,儘管它有點不同。 –