2017-10-20 118 views
0

我有一個類似的問題: How to retrieve multiple columns from non-entity type sql query?C#實體框架文本的SQL查詢包裝

我需要實現方法string[,] DirectQuery(string sqlText, string[] param)這基本上是一個C#相當於SQL Server Management Studio中的。

用戶應該輸入的SQL查詢作爲文本串(+字符串參數,以避免SQL注入)和接收回包含該查詢的結果的字符串矩陣。

在內部,我使用實體框架。

這裏是我的實現:

public string[,] DirectQuery(string sqlQuery, string[] param) 
{ 
     //discover how many fields are specified in the select clause 
     string ip = sqlQuery.ToLower().Split(new string[] { "from" }, StringSplitOptions.None)[0]; 
     int cols = ip.Count(y => y == ',') + 1; 

     //execute the query 
     DbRawSqlQuery<string> res = param != null ? _context.Database.SqlQuery<string>(sqlQuery, param) : _context.Database.SqlQuery<string>(sqlQuery); 

     //wrap everything in a matrix to return 
     return res.ToArray().Array2Matrix(res.ToArray().Length /cols, cols); 
    } 

其中

public static T[,] Array2Matrix<T>(this T[] flat, int rows, int cols) where T : class 

是變成平坦的陣列到rows x cols矩陣我的自定義方法。

如果在select子句中用戶指定了單個屬性,那麼工作正常,但在需要2+字段的情況下,執行DirectQuery會觸發運行時異常dbrawsqlquery he data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types。這是完全合理的,但由於查詢可以是任何我不能創建自定義類來包裝每一個可能的結果。

你有什麼建議?

+1

如果你真的* *要允許用戶輸入原始的SQL查詢,然後執行他們自己的名義,EF可能是*不*這個正確的工具。你應該看看像Dapper.NET(其中的權力這個網站,例如),很容易使原始的SQL的執行並打開結果變成漂亮的.NET對象與 –

+0

感謝很多工作,它工作得很好。但我仍然遇到一些與參數有關的問題。用戶在查詢中指定一定數量的參數,並按照他們的喜好命名(@ p0,@customerId,@ foo,...),並將其各自的值傳遞給字符串[]。如果我直接傳遞給查詢方法,則Dapper會觸發異常params string [];相反,它需要像'new {p0 =「17R13DT_GP_02_MP2」,...}「這樣的結構。有沒有更緊湊的方式來做到這一點? – jjhorn

回答

0

問題是你正在使用一個方法 - DbRawSqlQuery,必須告訴它什麼類型,你告訴它期望只是一個字符串,所以它不知道如何處理多個返回柱。

也許如果你指定string[]IEnumerable<string>或東西它的工作?或者,您可以定義一系列具有1,2,3,4等值的對象,並在運行時檢測項目的數量並使用正確的類......但這看起來很荒唐。

真的不過,我建議不使用EF有人上文建議。找到可以返回動態對象的東西,或者直接使用ADO.Net。

+0

是否有可能使用Reflection創建具有1,2,3,4等值的運行時對象? – jjhorn

+0

可能嗎?也許。但是通過在運行時創建類型,你只能在運行時訪問屬性,所以你基本上會丟掉任何編譯時類型檢查能力......你基本上創建的是一個數組/ list/table類型的東西,它使用反射來訪問它的成員,所以毫無疑問,與僅僅使用數組相比,它是*非常低效的。我真的不想重新發明輪子 - 只要使用已經存在的類型並直接使用ADO.Net並使用DataTable即可。 – GPW