当前位置: 首页 > 面试题库 >

在SQL中基于一对多表关系填充对象

越昊穹
2023-03-14
问题内容

我在C#中有一个这样的对象:

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

假设我在SQL中有两个表,一个表定义了窗口小部件属性,另一个表为单个窗口小部件保存了许多记录,假设窗口小部件的收藏夹编号:

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();
    }
}

我的问题是我应该继续使用这种类型的方法,还是建议执行表联接。如果建议使用表连接,那么填充对象的最佳设计模式是什么?我的问题是我必须创建一些逻辑来过滤出重复的行,当我获得所有小部件而不是一个时,它特别复杂。


问题答案:

我将使用表联接。创建一个遍历结果的方法非常简单。即使查询多个窗口小部件及其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;
  }

然后,按照以下方式重写您的方法:

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();
        }
    }
}


 类似资料:
  • 问题内容: 我有两个表: 帖子: 和标签: posts.tags和tags.tag都是文本类型。我想要的是从tag.tag到帖子中的行的关系,这样查询将给我对应于帖子1和2的行,查询给我2和3,给我1和3,依此类推。 我已经看过外键,但是我不确定这是我想要的。(老实说,我不确定它是做什么的)。据我所知,外键必须等于表的主键/唯一列。但是我想要的是诸如此类的所有行。我还希望能够获得以b开头的所有标签

  • 根据和的公共列在中使用填充列的最佳方法是什么? 得到: 编辑:我还想将列名更改为,这样预期的输出如下所示: 尝试过: 它发现了错误: 更新2: : :

  • 问题内容: 我有两个表A和Band,A与B之间的关系是A —>一对多—> B 通常,对于A的每条记录,我都有一个B的记录。 我正在尝试编写一个查询,该查询将为我提供A的 唯一 记录列表,其中B中的 记录 超过 一个(多个) 。 我很困惑,因为我只完成了基本的sql查询,而这对我来说似乎很复杂。 可以请一个人指导我正确答案或给我解决方案。 编辑: 好吧,我尝试了下面的事情,它给了我一个错误 从A a

  • 我需要在我的数据库中创建多个多对多的关系。 有一个“主”表,我们称之为“项目”。 然后有3个表包含“选项”。 假设我们有:品类、地域、用户。这些保存的唯一信息是项目的名称和ID。 可以将多个类别、区域和用户分配给多个项目。 因此,我有两个选项来创建这种关系: 1)为每个'选项'表创建关系表。每个表包含两列:project_id和category_id、region_id或user_id。使用这种方

  • 用户表结构:用户 id、名称、用户名、密码、创建时间、更新时间 文章表结构:文章 id、标题、内容、创建时间、更新时间 关系表:文章\用户 id、文章id、用户id处于活动状态、创建时间、更新时间 标签 id、名称、用户id、创建时间、更新时间 透视表项目用户与标记的关系。表:文章\用户\标签 标签号,物品号,用户号 我想连接这些表,以便可以像这样或类似的格式访问 并且应该能够创建/更新smth,