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

2023-12-01

我在 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();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 SQL 中基于一对多表关系填充对象 的相关文章

随机推荐

  • 如何在JavaScript值分配中分配php变量? [复制]

    这个问题在这里已经有答案了 可能的重复 如何将 JavaScript 变量传递给 PHP 如何在此 php 变量上分配 javascript 值 你根本无法做到这一点 你需要了解客户端 服务器端编程之间的区别 你不能将 Javascript
  • CORBA 通信问题

    这可能太本地化了 但我希望有人能帮助我正确地阐明我的问题 因此 我们有一个前端 Web 服务器 它使用 CORBA 与后端应用程序服务器进行通信 我被要求将后端应用程序移植到 LINUX 机器上 我照做了 但是 为了测试它 我尝试将前端 W
  • 从 Applet 打印 JasperReport

    我开发了网络应用程序 它使用JasperReports用于报告目的 因为我必须使用小程序在客户端查看报告 我可以正常在小程序中看到报告 但是当涉及到打印时 当我单击查看器中的 打印 按钮时 它会抛出一个异常 我可以在 Java 控制台中看到
  • 基于频率水平的子集[重复]

    这个问题在这里已经有答案了 我想生成一个 df 它选择与 ID 关联的行 而 ID 又与名为 cutoff 的变量关联 对于本示例 我将截止值设置为 9 这意味着我要选择 df1 中 ID 值与超过 9 行关联的行 我的代码的最后一行生成了
  • 如何在 asp.net 中使用“Post/Redirect/Get”(又名“Redirect after Post”)

    在 asp net 中的某些操作之后进行刷新似乎会使它们再次发生 即使该操作没有意义 想想双重删除 处理这种情况的 Web 方法是在发布后重定向以获得可以刷新的页面的干净版本 而无需将操作重新发布到 Web 服务器 我怎样才能用 ASP N
  • 接受带有自签名证书的 HTTPS 连接

    我正在尝试使用 HTTPS 连接HttpClientlib 但问题是 由于证书不是由公认的证书颁发机构 CA 签署的 例如Verisign 全局标志等 列在 Android 可信证书集中 我不断收到javax net ssl SSLExce
  • 如何通过标题而不是绘图区域来对齐多个绘图?

    我在用着egg对齐页面上的多个绘图 我想知道是否可以通过标题对齐两列a and c 而不是情节面积 谢谢 Code library egg library grid p1 lt ggplot mtcars aes mpg wt colour
  • logback.xml 的 perf4j 设置

    大家好 我想知道 logback xml 与 perf4j 一起使用时的确切配置设置 我在 logback xml 中创建此配置
  • 在 SAS-IML 中循环名称?

    如何将名称为主干 后缀的 SAS 数据集读取到 IML 中 词干作为 SAS 宏变量给出 我打算使用的后缀位于 IML 中的字符串向量中 在 R 中我会使用 suffix lt c s1 s2 for s in suffix data lt
  • 如何在Windows Phone 7中使用AES/ECB/PKCS7Padding算法?

    我是 Windows Phone 开发新手 如何在 WP7 中使用 AES ECB PKCS7Padding 算法 在谷歌搜索时 我看到了很多关于 Bouncy Castle 的建议 但我对这个充气城堡并没有很清楚的了解 这是一种算法吗 我
  • 如何在 Swift 中检查 URL 的有效性?

    尝试让应用启动默认浏览器访问某个 URL 但前提是输入的 URL 有效 否则会显示一条消息 指出该 URL 无效 我该如何使用 Swift 检查有效性 如果您的目标是验证您的应用程序是否可以打开 URL 那么您可以执行以下操作 虽然 saf
  • 在 Raspberry PI 上安装“ring.cx SIP 客户端”

    情况 我希望在我的 Raspberry Pi 上进行基于终端 无头 的 SIP 呼叫 并且我已经使用 linphone 尝试过此操作 RaspberryPI 使用 linphonec 或替代 SIP 软电话进行 SIP 出站呼叫 由于我目前
  • 直接从字节数组播放声音 - Java

    我正在尝试使用以下方法播放存储为字节数组的声音 byte clickSamples getAudioFileData sound wav ByteBuffer buffer ByteBuffer allocate bufferSize 2
  • Geoserver - 使用 DWITHIN 过滤点

    首先 我是 Geoserver 和 Openlayers 的新手 我一直试图在 Geoserver 端使用图层预览页面来使用 Openlayer 查看器查看我的图层 我最终会将其实现为 Openlayers WFS GET 请求 我想要完成
  • 强制 eclipse 重新加载 Python 模块

    我已经启动了一个 Eclipse PyDev 项目 并发现BeautifulSoup失踪 我安装它使用easy install 现在脚本可以从命令行正常运行 然而 Eclipse 仍然认为BeautifulSoup未安装 显示烦人的错误消息
  • 如何为 PostgreSQL JSONB 平面文本数组建立索引以进行模糊和右锚定搜索?

    PostgreSQL 版本 9 6 The events表有一个visitorsJSONB 列 CREATE TABLE events name VARCHAR 256 visitors JSONB The visitors列包含一个 平面
  • Intellij IDEA 和 Maven,在每个小更改上禁用读取 pom.xml,即使没有保存

    这导致 intellij 变得缓慢并冻结 这非常烦人 看起来好像它分析了类似于 pom xml 的其他文件 导致其他地方也冻结 可以禁用此功能吗 In Windows Operating system Press Ctrl Alt S or
  • apache tomcat 503自定义错误页面

    我使用 mod jk 设置在端口 80 上运行 apache2 和 tomcat6 不是从 apt 存储库安装 而是手动下载并安装 通过浏览器访问 jsp servlet 页面http myapp mydomain com 虚拟主机是在 t
  • 灯亮了但立方体没有出现

    我正在尝试在立方体上使用照明 但我不明白哪里出了问题 我可以看到光源 但屏幕的其余部分显示为黑色 所以我不明白为什么立方体消失了 这是代码 Header Inclusions include
  • 在 SQL 中基于一对多表关系填充对象

    我在 C 中有一个像这样的对象 private ClassWidget public int ID public List