我正在使用LINQ to SQL来调用带有单个结果集的存储过程(我已经找到了很多关于处理多个结果集的信息,但这不是我正在做的事情)。结果集实际上是连接在一起的3个表中的所有列,并且我有3个表的LINQ to SQL实体。架构是这样的:
基本上,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,它实际上会运行一个将Customers连接到Orders的SQL语句,从两者中选择所有列,然后返回填充了Orders集合的不同Customer对象。我想要对对象进行同样的翻译,但是从我的存储过程的结果开始。
我已经尝试将存储过程的返回类型设置为Customer,但是通过上面的示例,我得到了7个Customer对象(5个重复项)的集合,这些对象没有填充Orders集合。如果我然后迭代其中一个Customer对象的Orders集合,我看到它们是懒惰加载到数据库的另一次往返。然后我尝试将返回类型设置为Product,并且我确实获得了7个产品,但是如果我尝试访问它们,则它们的Order属性通过另一个往返延迟加载。
我还尝试将结果视为IMultipleResults,调用GetResult&lt; Customer&gt;()和GetResult&lt; Order&gt;()和GetResult&lt; Product&gt;()并手动将它们拼接在一起。但是,在这种情况下,只有第一次调用GetResult&lt;&gt;()才会返回一些内容(三种实体类型中的任何一种都可以使用,但仅适用于第一次GetResult&lt;&gt;()调用)。第二个和第三个GetResult&lt;&gt;()调用返回null。
感谢任何人提供的任何帮助。我一直在想我要么丢失一些简单的东西,要么LINQ to SQL没有提供任何公共API来执行此操作(即使它似乎在上面的LoadsWith示例中单独执行此操作)。
答案 0 :(得分:0)
我能想出的最佳解决方案是:
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行)。它确实涉及修改sproc,但它实际上应该减少数据库中的数据传输,因为你没有重复所有更高级别的数据,如加入所有表所做的(在上面的例子中重复每个Product的Customer和Order列)