2011-01-31 60 views
0

我正在構建用戶在SQL Server數據庫上執行臨時查詢的功能。由此產生的查詢將採取以下基本形式:用C#構建一個靈活的參數化adhoc查詢,SQL

SELECT <ONE TO MANY USER SELECTED FIELDS> 
FROM <ONE TO MANY TABLES DETERMINED BY FIELDS SELECTED BY USER> 
WHERE <ZERO TO MANY CRITERIA FOR THE SELECTED FIELDS> 

這是保證選擇最有可能跨越多個表。 某些(不是全部)字段對於特定字段可能有0個或更多的過濾標準。

我的應用程序使用ASP.NET MVC 2中使用C#的默認EF4類。我目前正在傳入一個名爲QueryItem的對象,其中包含特定條件的所有信息。

我的問題(S)是:

  1. 是什麼編碼這種最好的方法? (我下面的日期代碼示例)。
  2. 這可以用Linq2SQL完成,還是應該用ADO.NET(我現在的方法)
  3. 如果ADO.NET是最好的方法,你如何訪問EF4中的DBConnection?

注:我打算將此重構爲SQLParameter對象,以防止SQL注入。我現在的目標是首先開發查詢的最佳實踐。

QueryItem類:

public class QueryItem 
{ 
    public bool IsIncluded { get; set; } 
    public bool IsRequired { get; set; } 

    public string LabelText { get; set; } 
    public string DatabaseLoc { get; set; } 
    public List<string> SelectedValue { get; set; } 

    public List<SelectListItem> SelectList { get; set; } 
} 

查詢解析代碼

foreach(QueryItem qi in viewModel.StandardQueryItems) 
    { 
     string[] dLoc = qi.DatabaseLoc.Split(new Char[] { '.' }); //Split the table.fieldname value into a string array 

     if(qi.IsIncluded == true) //Check if the field is marked for inclusion in the final query 
     { 
      fields.Append(qi.DatabaseLoc + ","); //Append table.fieldname to SELECT statement 

      if(!tables.ToString().Contains(dLoc[0])) // Confirm that the table name has not already been added to the FROM statement 
      { 
       tables.Append(dLoc[0] + ","); //Append the table value to the FROM statement 
      } 
     } 

     if(qi.SelectedValue != null) 
     { 
      if(qi.SelectedValue.Count == 1) 
      { 
       query.Append(qi.DatabaseLoc + " = '" + qi.SelectedValue[0].ToString() + "'"); 
      } 
      else 
      { 
       foreach(string s in qi.SelectedValue) 
       { 
        //Needs to handle "IN" case properly 
        query.Append(qi.DatabaseLoc + " IN " + qi.SelectedValue.ToString()); 
       } 
      } 
     } 
    } 
+2

不要這樣做!提供一個豐富的'約束'界面來創建查詢,而不是...已經有一個用戶創建即席查詢的工具..它叫做SSMS – 2011-01-31 23:42:32

+0

@mitch小麥,涉及一個沒有it部門的公司的用例如何並希望查詢他們的數據庫?似乎這個建議只適用於理想情況下,而不是大多數小企業所處的環境。 – 2011-01-31 23:54:23

回答

0

我已經在一個單一的參數傳遞到有類似的系統,以你所描述的過去存儲過程的類型爲xml。通過這樣做,您實際上可以指定(在xml中)所有您想要報告的內容,並構建返回所需結果所需的SQL。

這也使得你的C#代碼更容易,因爲你所要做的就是生成一些你的程序將讀取的xml。生成動態SQL絕對不是你應該使用的東西,除非你必須使用,但是當你想允許用戶動態選擇他們想要報告的東西時,它幾乎是唯一的方法去做。

您的另一種選擇可能是查看Reporting Services - 這將允許用戶選擇他們想要查看的字段,並在他們自己的部分保存特定的「報告」,然後他們可以返回並再次運行它任何時候都可以。如果他們不具備精通計算機的功能(如果報告生成器只需要數據並且沒有特殊功能,那麼報告生成器更容易完成),您也可以爲他們創建報告。

無論採取哪種方式,您都需要確定哪種方案最適合您。 (對於任何需要生成動態sql並試圖瞭解混亂背後的邏輯的人來說,我感到很抱歉)。

舉報服務:非常容易吐出看起來不錯的報告,但它不夠靈活,並且不是免費的。