I am using LINQ to SQL to call a stored procedure with a single result set (I have found a lot of information about handling multiple result sets, but that is not what I am doing). The result set is actually all columns from 3 tables joined together, and I have LINQ to SQL entities for those 3 tables. The schema is something like this:
- Customer 1
- Order 1
- Product 1
- Product 2
- Product 3
- Order 2
- Product 4
- Order 1
- Customer 2
- Order 3
- Product 5
- Order 4
- Product 6
- Product 7
- Order 3
Basically, 1 Customer to many Orders, 1 Order to many Products. So the result set of the stored proc is actually one row per Product, but each row includes all of the Order and Customer columns. In the above example, the stored proc would return 7 rows.
So the question is: how can I get 2 Customer objects out of LINQ to SQL, each having their Orders collection filled, and each Order object having its Products collection filled all from the results of the stored proc?
I know that if you do something like (dc is the 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;
...and then watch the SQL that gets generated, it will actually run one SQL statement that joins Customers to Orders, selecting all columns from both, and then return to you the distinct Customer objects with their Orders collections filled. I am wanting this same kind of translation to objects, but from the results of my stored proc.
I have tried setting the return type of my stored proc to Customer, but with the example above, I get a collection of 7 Customer objects (5 duplicates) which do not have their Orders collection filled. If I then iterate over the Orders collection of one of the Customer objects, I see that they are lazy loaded with another round trip to the database. I then tried setting the return type to Product, and I do get the 7 products, but their Order property is lazy loaded via another round trip if I try to access it.
I have also tried treating the result as an IMultipleResults, calling GetResult<Customer>() and GetResult<Order>() and GetResult<Product>() and manually piecing them together. In this case, though, only the first call to GetResult<>() will return something (any of the three entity types will work, but only for the first GetResult<>() call). The second and third GetResult<>() calls return null.
Thanks for any help anyone can provide. I keep thinking I am either missing something easy, or LINQ to SQL doesn't offer any public API to do this (even though it appears to do this on its own in the LoadsWith example above).