Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用LINQ to SQL从存储过程中获取多维结果_Linq_Linq To Sql_Stored Procedures - Fatal编程技术网

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

使用LINQ to SQL从存储过程中获取多维结果,linq,linq-to-sql,stored-procedures,Linq,Linq To Sql,Stored Procedures,我使用LINQ to SQL调用一个带有单个结果集的存储过程(我发现了很多关于处理多个结果集的信息,但这不是我要做的)。结果集实际上是来自3个表的所有列连接在一起,我为这3个表提供了LINQ到SQL实体。模式如下所示: 客户1 订单1 产品1 产品2 产品3 订单2 产品4 客户2 订单3 产品5 订单4 产品6 产品7 基本上,一个客户对应多个订单,一个订单对应多个产品。因此,存储过程的结果集实际上是每个产品一行,但每行包括所有订单和客户列。在上面的示例中,存储的p

我使用LINQ to SQL调用一个带有单个结果集的存储过程(我发现了很多关于处理多个结果集的信息,但这不是我要做的)。结果集实际上是来自3个表的所有列连接在一起,我为这3个表提供了LINQ到SQL实体。模式如下所示:

  • 客户1
    • 订单1
      • 产品1
      • 产品2
      • 产品3
    • 订单2
      • 产品4
  • 客户2
    • 订单3
      • 产品5
    • 订单4
      • 产品6
      • 产品7
基本上,一个客户对应多个订单,一个订单对应多个产品。因此,存储过程的结果集实际上是每个产品一行,但每行包括所有订单和客户列。在上面的示例中,存储的proc将返回7行

因此,问题是:如何从LINQ到SQL中获取两个客户对象,每个客户对象的订单集合已填充,每个订单对象的产品集合已填充,所有这些都来自存储过程的结果

我知道,如果您执行以下操作(dc是LINQ到SQL数据上下文)

var options=new DataLoadOptions();
options.LoadWith(c=>c.Orders);
dc.LoadOptions=选项;
var客户=来自dc中的c。客户选择c;
…然后观察生成的SQL,它实际上会运行一条SQL语句,将客户连接到订单,从这两个列中选择所有列,然后返回不同的客户对象,并填充其订单集合。我希望对对象进行同样的转换,但是要从存储过程的结果进行转换

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

我还尝试将结果作为IMultipleResults处理,调用GetResult()和GetResult()以及GetResult(),并手动将它们拼接在一起。不过,在本例中,只有对GetResult()的第一次调用将返回某些内容(三种实体类型中的任何一种都可以,但仅适用于第一次GetResult()调用)。第二个和第三个GetResult()调用返回null


谢谢任何人能提供的帮助。我一直认为我缺少了一些简单的东西,或者LINQ to SQL没有提供任何公共API来实现这一点(尽管在上面的示例中,它似乎是自己实现的)。

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

  • 修改存储过程以实际返回多个结果集(上述示例中的客户、订单和产品)
  • 在LINQ到SQL端,像往常一样使用IMultipleResults(有很多文档和示例)来获取这3个独立的IEnumerable
  • 创建每个非根实体的分组集合,即
    var groupedOrders=allReturnedOrders.GroupBy(order=>order.CustomerID)
    var groupedProducts=allReturnedProducts.GroupBy(p=>p.OrderID)
  • 循环遍历非叶对象,并使用
    EntitySet.SetSource()
    方法填充其关联对象的集合,即
    customer.Orders.SetSource(groupedOrders.Single(orderGroup=>orderGroup.Key==customer.CustomerID)
  • 这将从内存中的DBML中获取常用的实体对象,并且它不是很多代码(创建的层次结构中每层2-3行)。它确实涉及修改存储过程,但实际上应该减少从数据库传输的数据,因为您不会像连接所有表那样重复所有更高级别的数据(对上例中的每个产品重复“客户”和“订单”列)

    var options = new DataLoadOptions();
    options.LoadWith<Customer>(c => c.Orders);
    dc.LoadOptions = options;
    
    var customers = from c in dc.Customers select c;