1

C#.NET 4.0でジェネリック関数を記述して、データベース文字列とクエリ文字列を送信し、結果を返すことを検討しています。

C#に精通しておらず、さまざまなオブジェクトがあるため、この情報を返すための最良のオプションが何であるかはよくわかりません。

私は、、があることを知っていますDataTableDataSetそしてそれは本当にそれについてです。私が探しているのは、かなり効率的で、データメンバーに簡単にアクセスできるオブジェクトです。自分で作成しても問題はないと確信していますが、.NET4.0にはアクセスできる他のオブジェクトが必要であることはわかっています。

4

5 に答える 5

4

このような設計の問題は、セキュリティとSQLインジェクションの防止のためのベストプラクティスを使用することが非常に難しいことです。純粋なSQLステートメントを関数に渡すと、慎重に行わない限り、SQLインジェクションを防御する機能がほとんどなくなります。

原則として、ユーザー入力を取り込む場合は、パラメーター化されたストアドプロシージャ、またはパラメーター化されたクエリのいずれかを使用していることを確認する必要があります。推奨されるパターンは、ステートメントと、正しい数のパラメーター値を含むオブジェクト型の配列を渡し、関数にパラメーターコレクションを作成することです。

パターンとプラクティスライブラリのMicrosoftデータアプリケーションブロックを使用します。これには、これを非常に簡単にする機能が含まれています。

これを使用する場合、ConnectionStringはapp.configまたはweb.configに保存され、接続文字列のNAMEを渡すと、データアプリケーションブロックコードがそれを検索し、コマンドを作成し、接続し、クエリ。

このパターンを使用すると、コードは次のようになります。

public static DataSet ExecuteDataset(string CallingApp, string ConnectionStringName, string StoredProcName, object[] ParameterValues)
{
        DataSet ReturnValue = new DataSet();

        Microsoft.Practices.EnterpriseLibrary.Data.Database db = Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(ConnectionStringName);
        try
        {
            ReturnValue = db.ExecuteDataSet(StoredProcName, ParameterValues);
        }
        catch (Exception ex)
        {
            // a bunch of code for exception handling removed            
        }


        return ReturnValue;
 }

これは、DataSetを取得するためのコードです。利用できる関数は他にもたくさんあり、このコードは最新バージョンのデータアクセスライブラリでは機能しない可能性があります。少し古いバージョンを使用していますが、これにより、使いやすさがわかります。

于 2012-04-30T15:44:46.820 に答える
2

新しく改善された方法はそれを行うことではなく、必要なデータを取得するための方法を持っていることです。

たとえば、CustomerOrderクラスを定義します。次のような関数を持つデータベースモジュールを用意します。

GetOpenOrdersForCustomer(int argCustomerID) 

それはあなたにそれらのコレクションを返します。

EntityFrameworkPOCOなどを検索します。

DataSetそしてDataTable、この種のものの初期の化身であり、それらはかなり重く、たくさんの荷物があります。

もう少しハンドコーディングを行う必要がある場合。IDataReader、などのインターフェイスはIDbCommand IDbConnection、バックエンドがSQL Server、MySqlなどであるかどうかなど、コード内の多くの実装の詳細からユーザーを分離します。

それでも、アプリケーションコードで、のDataTableようなものを渡さない方がよいでしょう。SqlCommand

コード全体にデータベーススキーマを塗りつぶす機会が多すぎるため、技術的負債の可能性が非常に高く、すぐに実現される可能性があります。

すべて非表示にします。Code First POCOでは、実際には見えません。

于 2012-04-30T15:42:58.363 に答える
1

NHibernateのようなORMの使用について考えたことはありますか:http://nhforge.org/Default.aspx

それはデータベースに関連するすべてを行い、あなたは素晴らしいオブジェクトクラスで作業するでしょう。

それ以外の場合、関数はDatatableを返すことができ、別の関数を記述してDataTableを取得し、データをオブジェクトクラスに抽出できます。例えば。この新しい関数は次のようになります。

パブリックオブジェクトPopulateData(DataTableテーブル、列挙型ClassType); //または同様のもの

次に、リフレクションを使用してDataTable列とクラスオブジェクトをマップできます。

ただし、ORMの使用をお勧めします。

于 2012-04-30T15:38:16.147 に答える
1

カバーしたいシナリオによって異なります。たとえば、MVCアプリケーションでは、エンティティフレームワークに基づいてデータレイヤーをデプロイするのはかなり保守可能です。これは、テストが容易で、データベースとの通信が単純なオブジェクトを介して非常に簡単であるためです。

別のアプローチは、エンタープライズライブラリのデータアプリケーションブロックなどのすでに開発されたコンポーネントを使用するか、カスタムデータベースファクトリを開発することです...それは開発の目的によって異なります。

私たちが話しているアプリケーションの種類について詳しく教えてください。それは既存のデータベースですか、それとも新しいデータベースですか。

別の質問。クエリ文字列を渡すために正確に何を期待しますか?あなたがSQL文を渡すことを気にするなら、私はあなたが避けるべきであるそれは非常に悪くて危険な習慣であるとあなたに言うでしょう。

よろしくお願いします。

于 2012-04-30T15:42:03.260 に答える
1

あなたは次のようなものが欲しいかもしれません:

public static DbDataReader Query(
    string connectionString, string selectCommand, 
    params KeyValuePair<string, object>[] parameters)
{
    var connection = new OleDbConnection(connectionString);
    var command = new OleDbCommand(selectCommand, connection);

    foreach (var p in parameters)
        command.Parameters.Add(new OleDbParameter(p.Key, p.Value));

    var result = command.ExecuteReader();
    return result;
}

例として使用されるOleDb。

于 2012-04-30T15:50:47.580 に答える