linq - 使用 LINQ to SQL 从存储过程中获取多维结果

标签 linq linq-to-sql stored-procedures

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

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

基本上,1 个客户对应多个订单,1 个订单对应多个产品。因此,存储过程的结果集实际上是每个 Product 一行,但每一行包含所有 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 语句,将 Customers 与 Orders 连接起来,从两者中选择所有列,然后返回不同的 Customer 对象,并填充其 Orders 集合。我想要对对象进行同样类型的转换,但是来 self 的存储过程的结果。

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

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

感谢任何人可以提供的帮助。我一直在想,我要么错过了一些简单的东西,要么 LINQ to SQL 不提供任何公共(public) API 来执行此操作(尽管它在上面的 LoadsWith 示例中似乎是自行执行此操作)。

最佳答案

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

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

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

关于linq - 使用 LINQ to SQL 从存储过程中获取多维结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/971095/

相关文章:

c# - 为 EntitySet<T>、IQueryable<T> 和 IEnumerable<T> 创建可重用谓词

c# - 存储过程性能 - 这是 WILD?

c# - 如何在 Linq 上获得左连接

c# - List<IEnumerator>.All(e => e.MoveNext()) 不会移动我的枚举数

c# - linq返回使用元组

asp.net - 删除事件后GridView不刷新

mysql - shell脚本中mysql存储过程的关联数组

mysql - 创建过程 MySQL 错误无描述

.net - 在选择部分中使用子选择的 Linq to Entities

c# - 如何做 C# Linq Join Equals Where