如何使用 ADO.NET 从具有一对多关系的 DAL 层中的多个表中返回数据

Posted

技术标签:

【中文标题】如何使用 ADO.NET 从具有一对多关系的 DAL 层中的多个表中返回数据【英文标题】:How to return Data from multiple tables in DAL layer with one-to-many relationship using ADO.NET 【发布时间】:2016-04-28 15:33:58 【问题描述】:

我在数据库中有一个customer表和orders表是一对多的关系,我的需求是为每个客户获取对应的订单列表。enter image description here

这是为 customerid = 1 完成的订单列表

我可以通过数据库的多次循环调用来做到这一点(例如 - 首先我收集了客户列表,然后对于每个客户,我在相应的 listDTO 中收集了他们的订单列表,最后将带有订单 DTO 的客户列表返回给BAL 层。

我认为多次调用数据库来获取数据是不好的。有什么有效的方法吗?

【问题讨论】:

使用JOIN,卢克。 您可以在此处发布您的一些代码...否则在 SQL 中您可以在下面执行...您可以添加一些 Select C.*, O.* FROM Customers C Left Join Orders O on C.CustomerID = O.CustomerID 谢谢,加入可能会有所帮助,但在一对多关系的情况下,我将为每个客户获取多条记录,之后我需要运行循环来创建所需的 DTO。我说的对吗? 【参考方案1】:

虽然您可以进行连接,但就像您说的那样,您将获得每个订单重复客户信息的多条记录,而您的代码必须对其进行重复数据删除。

我喜欢使用 SqlDataReader 对多个结果集的支持来简化此操作。 https://msdn.microsoft.com/en-us/library/hh223698(v=vs.110).aspx

所以你的 SQL 看起来像这样:

--Assume that @CustomerId is a parameter (always use parameters!)
SELECT CustomerId, CustomerName
  FROM Customer
 WHERE CustomerId = @CustomerId

SELECT OrderId, OrderDate --all your order columns
  FROM Orders
 WHERE CustomerId = @CustomerId

然后在你的 ADO.Net 代码中:

using (var reader = command.ExecuteDataReader())

    while (reader.Read())
    
        //read first result set
    

    reader.NextResult();

    while (reader.Read())
    
        //read secondresult set
    

或者更好的是,使用异步版本的 ExecuteDataReader、Read、NextResult :-)

【讨论】:

谢谢,@Cleverguy25。这很有帮助。【参考方案2】:

如果您使用的是 SQL 2016,这可以通过 JSON 路径查询很好地完成 返回 JSON 的层次结构,然后可以将其反序列化为您的对象,或者可能传递给客户端。

SELECT
            O.ORDER_ID orderId,
            O.ORDER_NAME orderName,
            O.ACTIVE_START orderDate,
            (SELECT
                OI.ORDER_ITEM_ID itemId,
                OI.NAME name,
                OI.COMMENTS comments
            FROM
                dbo.ORDER_ITEM OI
            WHERE
                O.ORDER_ID = OI.ORDER_ID
            FOR JSON PATH) items
        FROM
            dbo.[ORDER] O
        WHERE
            O.PERSON_ID = @PERSON_ID
        FOR JSON PATH;

这会返回类似的东西

[
  
    "orderId": 21,
    "orderName": "my first order",
    "orderDate": "2016-09-18T11:01:41",
    "items": [
      
        "itemId": 41,
        "name": "pizza",
        "comments": "Extra Cheese Please"
      ,
      
        "itemId": 42,
        "name": "italian sandwich",
        "comments": "No peppers"
      
    ]
  
]...

在https://github.com/ahhsoftware/EzAdoVSSolution 有一个包含 ado 包装器的 git 项目,用于促进这些类型的调用,这可能是您感兴趣的内容。

【讨论】:

以上是关于如何使用 ADO.NET 从具有一对多关系的 DAL 层中的多个表中返回数据的主要内容,如果未能解决你的问题,请参考以下文章

如何以一对多关系访问数据?

如何从一对多单向关系中获取“多”部分中的对象?

从数据库中获取具有一对多关系的特定产品

如何将具有一对多关系的表组合成 1 行记录

ADO.net 如何将数据库单元格变成整数?

在 Postgis 中,如何从空间表和相关(非空间)表之间的一对多关系构建 Geojson