2011-08-02 13 views
3

で1対多のテーブルのリレーションシップに基づいてオブジェクトを取り込み他の1つのウィジェットのために多くのレコードを保持している、のは、ウィジェットの好きな数字を言ってみましょう:私はこのようなC#でオブジェクトを持っているSQL

widgets 
----------- 
id (int, not null) 
// other properties ... 

widget_nums 
---------- 
widget_id (int, not null) 
num (int) 

私は自分自身が頻繁に私はちょうど1クエリを作成するテーブルを結合することができます知っているにもかかわらず、このオブジェクトを移入するには、2つのSQLクエリを実行見つけます。その理由は、データが重複している結果セットを繰り返し処理するのではなく、必要なデータだけをオブジェクトに取り込むほうが簡単に思えるからです。もちろん、このウィジェットの例は実際のシナリオに比べて大幅に単純化されています。ここにその例があります:

int WidgetID = 8; 
ClassWidget MyWidget = new ClassWidget(); 
using (SqlConnection conn = GetSQLConnection()) 
{ 
    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = @"SELECT id FROM widgets WHERE id = @WidgetID;"; 
     cmd.Parameters.AddWithValue("WidgetID", WidgetID); 
     using (SqlDataReader Reader = cmd.ExecuteReader()) 
     { 
      if (Reader.HasRows) 
       MyWidget.ID = GetDBInt("id", Reader); // custom method to read database result 
     } 
     cmd.CommandText = @"SELECT num FROM widget_nums WHERE widget_id = @WidgetID;"; 
     using (SqlDataReader Reader = cmd.ExecuteReader()) 
     { 
      if (Reader.HasRows) 
       while (Reader.Read()) 
        MyWidget.WidgetFavoriteNumbers.Add(GetDBInt("num", Reader)); 
     } 
     conn.Close(); 
    } 
} 

私の質問は、このタイプのアプローチを使用し続けるべきかどうか、またはテーブル結合を実行することが推奨されるかどうかです。テーブルジョインが推奨されている場合、オブジェクトを生成するための最良のデザインパターンは何ですか?私の問題は、重複行を除外するためにロジックを作成しなければならず、ウィジェットだけではなくすべてのウィジェットを取得しているときに特に複雑になります。

答えて

4

テーブル結合を使用します。結果をトラバースするメソッドを作成するのは簡単です。

using (SqlConnection conn = GetSQLConnection()) 
{ 
    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = @"SELECT id FROM widgets INNER JOIN widget_nums on .... WHERE id = @WidgetID;"; 
     cmd.Parameters.AddWithValue("WidgetID", WidgetID); 
     using (SqlDataReader Reader = cmd.ExecuteReader()) { 
      return MapReaderToWidget(reader).FirstOrDefault(); 
     } 
    } 
} 
0

テーブル結合を使用します。これは単一のSQLクエリを使用し、非常に高速です(現在のアプローチよりもはるかに高速です)。そして、ロジックが重複した行をフィルタリングするためには、それについての質問を思いつくことができます。データベースから必要なものを提供するクエリを開発するには時間がかかるため、結果に満足しています。

0

データ提供者としてAdo Entity FrameworkまたはLinQ to SQLに移行する必要があると思います。これは、時間を節約し、効率的な方法で必要なものを正確に実行するためです。

+0

を私はORMのアイデアを愛していますが、それが意味するものではありませんデバッグ時:次に、以下のようあなたの方法を書き換え、複数のウィジェットと、そのwidget_nums

private IEnumerable<ClassWidget> MapReaderToWidget(IDataReader reader) { var dict = new Dictionary<int, ClassWidget>(); while (reader.Read()) { var id = (int)reader["id"]; ClassWidget widget; if (!dict.TryGetValue(id, out widget)) { widget = new ClassWidget { ID = id, WidgetFavoriteNumbers = new List<int>(); }; dict.Add(id, widget); } widget.WidgetFavoriteNumbers.Add((int)reader["num"]); } return dict.Values; } 

を照会するとき、あなたも、この方法を使用することができますデータレイヤーを完全には知らないので、デバッグのためにそれを横断することになります。 – Coops

+0

申し訳ありませんが、私はあなたが意味するものを得ていませんでしたか? –

+0

私は経験は限られていますが、データプロバイダを使用するのではなく、独自のデータレイヤをコーディングした方がデバッグがずっと楽だと思いますか? – Coops

関連する問題