【问题标题】:Getting a multi-dimensional result out of a stored procedure with LINQ to SQL使用 LINQ to SQL 从存储过程中获取多维结果
【发布时间】:2009-06-09 16:18:42
【问题描述】:

我正在使用 LINQ to SQL 调用具有单个结果集的存储过程(我发现了很多关于处理多个结果集的信息,但这不是我正在做的)。结果集实际上是将 3 个表中的所有列连接在一起,并且我有这 3 个表的 LINQ to SQL 实体。架构是这样的:

  • 客户 1
    • 订单 1
      • 产品1
      • 产品 2
      • 产品 3
    • 订单 2
      • 产品 4
  • 客户 2
    • 订单 3
      • 产品 5
    • 订单 4
      • 产品 6
      • 产品 7

基本上,1 个客户对应多个订单,1 个订单对应多个产品。因此,存储过程的结果集实际上是每个产品一行,但每一行都包含所有 Order 和 Customer 列。在上面的示例中,存储过程将返回 7 行。

所以问题是:如何从 LINQ to SQL 中获取 2 个 Customer 对象,每个对象都填充了 Orders 集合,并且每个 Order 对象的 Products 集合都填充了存储过程的结果?

我知道,如果您执行类似的操作(dc 是 LINQ to SQL DataContext)...

var options = new DataLoadOptions();
options.LoadWith<Customer>(c => c.Orders);
dc.LoadOptions = options;

var customers = from c in dc.Customers select c;

...然后观察生成的 SQL,它实际上将运行一条 SQL 语句,将客户连接到订单,从两者中选择所有列,然后将填充了订单集合的不同客户对象返回给您。我想要这种对对象的相同类型的翻译,但来自我存储过程的结果。

我尝试将存储过程的返回类型设置为客户,但在上面的示例中,我得到了 7 个客户对象(5 个重复项)的集合,这些对象的订单集合没有填充。然后,如果我遍历其中一个 Customer 对象的 Orders 集合,我会看到它们是延迟加载的,并带有另一个到数据库的往返行程。然后我尝试将返回类型设置为 Product,我确实得到了 7 个产品,但是如果我尝试访问它们,它们的 Order 属性会通过另一个往返延迟加载。

我还尝试将结果视为 IMultipleResults,调用 GetResult() 和 GetResult() 和 GetResult() 并手动将它们拼凑在一起。但是,在这种情况下,只有第一次调用 GetResult() 会返回一些东西(三种实体类型中的任何一种都可以工作,但仅适用于第一次 GetResult() 调用)。第二个和第三个 GetResult() 调用返回 null。

感谢任何人提供的任何帮助。我一直在想我要么遗漏了一些简单的东西,要么 LINQ to SQL 没有提供任何公共 API 来执行此操作(即使在上面的 LoadsWith 示例中它似乎是自行执行此操作)。

【问题讨论】:

    标签: linq linq-to-sql stored-procedures


    【解决方案1】:

    我能想到的最佳解决方案是:

    1. 修改存储过程以实际返回多个结果集(上例中的客户、订单和产品)
    2. 在 LINQ to SQL 端像往常一样使用 IMultipleResults(有很多文档和示例)来获取这 3 个单独的 IEnumerables
    3. 创建每个非根实体的分组集合,即var groupedOrders = allReturnedOrders.GroupBy(order =&gt; order.CustomerID)var groupedProducts = allReturnedProducts.GroupBy(p =&gt; p.OrderID)
    4. 循环遍历非叶对象并使用EntitySet.SetSource() 方法填充它们的关联对象集合,即customer.Orders.SetSource(groupedOrders.Single(orderGroup =&gt; orderGroup.Key == customer.CustomerID)

    这会从内存中的 DBML 获取您常用的实体对象,并且代码量不是很多(您正在创建的层次结构中每个级别 2-3 行)。它确实涉及修改存储过程,但实际上应该减少从数据库传输的数据,因为您不会重复所有更高级别的数据,例如加入所有表会做的事情(在上面的示例中为每个产品重复客户和订单列) .

    【讨论】:

      猜你喜欢
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      相关资源
      最近更新 更多