2011-08-02 71 views
3

一个一对多表关系,我有这样的在C#中的物体的目标:填充基于在SQL

private ClassWidget 
{ 
    public int ID; 
    public List<int> WidgetFavoriteNumbers; 
} 

比方说,我在SQL两个表,一个定义窗口小部件的属性,以及其他适用于一个Widget多条记录,让我们说widget的喜爱的数字:

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

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

我发现自己经常执行两个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