簡體   English   中英

你在哪里把SQL語句放在你的c#項目中?

[英]Where do you put SQL Statements in your c# projects?

我可能會負責將vb6應用程序移植到c#。 此應用程序是一個與訪問數據庫交互的Windows應用程序。 數據訪問封裝在基本業務對象中。 基本上一個表的一個類。 現有的vb6業務對象通過DAO讀寫DB。 我以前寫了幾次DAL和ORM,但它們都只針對SQL Server。 這個將需要目標訪問和SQL服務器。 在以前的項目中,我會將SQL字符串放在業務對象的私有部分中,並可能將冗余的sql代碼(如連接,創建命令)移動到公共基類中以減少代碼。

這一次,我正在考慮將SQL字符串寫入.settings文件或其他鍵/值類型文本文件。 然后我會編寫一個sql實用程序來編輯這個文件,並允許我運行並測試參數化查詢。 這些查詢將在業務對象中按名稱引用,而不是將sql嵌入到代碼中。

我知道一種標准方法是為每個目標數據庫創建一個DAL,並具有要使用的DAL配置狀態。 我真的不想為每個數據庫創建兩個DAL類。 如果我只是通過keyname引用了正確的查詢並且具有正確的連接類型,那么似乎代碼會更少。

那么,你們這樣做嗎? 你怎么會或者你有沒有解決這個問題? 什么最適合你?

謝謝!

嗯,有很多選擇 - 所以它真的取決於你最迫切的需求是什么:-)

一種方法可能是在VS解決方案中將SQL語句創建為文本文件,並在“構建操作”中將其標記為“嵌入式資源”。 這樣,SQL就包含在生成的程序集中,並且可以在運行時使用.NET框架的ResourceManifestStream從中檢索:

private string LoadSQLStatement(string statementName)
{
    string sqlStatement = string.Empty;

    string namespacePart = "ConsoleApplication1";
    string resourceName = namespacePart + "." + statementName;

    using(Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
        if (stm != null)
        {
            sqlStatement = new StreamReader(stm).ReadToEnd();
        }
    }

    return sqlStatement;
}

您需要將“ConsoleApplication1”替換為sql語句文件所在的實際命名空間。 您需要通過完全限定名稱來引用它們。 然后,您可以使用以下行加載SQL語句:

string mySQLStatement = LoadSQLStatement("MySQLStatement.sql");

然而,這使得查詢相當“靜態”,例如,您無法在運行時配置和更改它們 - 它們直接被編譯為已編譯的二進制位。 但另一方面,在VS中,您可以在C#程序代碼和SQL語句之間實現清晰的分離。

如果你需要能夠在運行時調整和更改它們,我會將它們放入一個SQL表中,該表包含例如關鍵字和實際的SQL查詢作為字段。 然后,您可以根據需要檢索它們並執行它們。 由於它們位於數據庫表中,您還可以隨意更改,修復,修改它們 - 即使在運行時 - 也無需重新部署整個應用程序。

當我真的需要它時,我將查詢放入單獨的* .sql文件中,然后將它們包含在Resources.resx中。 其中有一個“文件”部分,允許您包含嵌入式資源文件。

之后,我可以使用生成的Resources.MyQuery屬性來保證資源的存在,並使我免於編寫自定義資源加載方法。

LINQ to DataSet聽起來像是你的方式。

如果你沒有在/ LINQ之前使用過.NET 3.5,那么你就可以享受一下。 LINQ將保存您在字符串文字中編寫原始sql,並為您提供更合理的創建查詢的方法。

無論如何,請檢查此鏈接以使用Access數據庫上的LINQ - http://msdn.microsoft.com/en-us/library/bb386977.aspx

我會告訴我不會把它放在哪里,我在一些繼承的代碼中看到的東西。 它是在Java中,但適用於任何語言

  • 一個基類,使用返回單個SQL語句的get方法,為SQL語句聲明受保護的靜態成員變量(inited為null)

  • 每個受支持的數據庫服務器的子類,具有分配給基類成員變量的init方法

  • 幾個使用基類方法檢索SQL語句的DA類

  • 應用程序啟動類,負責創建正確的子類對象並調用其init方法

我也不會解釋為什么我不會這樣做:-)

我們使用的一種方法是擁有一個連接到DB的類和調用過程的方法,並在方法參數中提供過程名稱。 所以所有的SQL代碼都在程序中。 我們會為不同的返回類型使用重載

class ConnectToSQL()
{
        //connectSql code (read from setting file i assume)

        XMLDataDocument runProcedure(string procedureName);
        int runProcedure(string procedureName);

        //etc....
}

如果我不得不為SQL和Access創建應用程序,我會使用一些IDAL接口,DALCommon具有通用功能實現,以及從DALCommon繼承的單獨DALSql和DALAccess,以及一些特定的東西,如異常,事務處理,安全性等。
我曾經在資源文件中保存存儲過程名稱或查詢。

如果SQL Query具有“where”原因,則上面顯示的嵌入解決方案可能不起作用,但對於同一個Query,下一次運行需要PropertyID ='113',因為PropertyID是讀入的。

很高興你問! 將您的sql放在QueryFirst .sql模板中。

它會作為嵌入式資源自動編譯到您的應用程序中,但您並不在意。 您只需在真實的SQL窗口中編寫它,連接到您的數據庫,使用語法驗證和表和列的智能感知,然后通過生成的Execute()方法使用它,並使用智能感知輸入和結果。

免責聲明:我寫過QueryFirst。

有時,與自定義報告應用程序一樣,您確實需要接受阻抗不匹配,並特別重視SQL。 在這些情況下,我建議如下:對於包含SQL字符串的每個模塊,創建一個靜態“SQL”類來保存它們。 一些SQL字符串可能需要參數,因此要保持一致並將每個字符串放在它自己的靜態方法之后。

我只為偶爾的自定義報告應用程序執行此操作,但它總是很好用,感覺清爽和解放。 幾個月后回來做一個增強,並在一個SQL.cs文件中找到等待你的所有SQL,這是非常好的。 只需讀取一個文件,它就會全部回來,而這通常是唯一需要更改的文件。

我認為在這些情況下不需要將SQL隱藏在資源或其他地方。 當SQL很重要時,那很重要。 有趣的是,越來越多的開發人員現在可以自由地將SQL與C#混合,包括我相信這個站點,因為從本質上講,這就是LINQ。

最后,一如既往,確保您不會受到SQL注入攻擊。 特別是如果涉及用戶輸入,請確保使用某種參數化並且不使用字符串連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM