Using LINQ to SQL to return Multiple Results

Using LINQ to SQL to return Multiple Results

In the LINQ in Action forum, a user asked about returning multiple result sets from a single stored procedure. Below is one way of dealing with this issue.

In the procedure, we used multiple results rather than a result with a return value (through RETURN or an OUTPUT parameter). Here we need to use the IMultipleResult rather than the default ISingleResult implementation. It appears that the designer does not map IMultipleResult in the final build, so we are going to need to do it ourselves. We mention this interface in chapter 8 but didn't have a chance to include a sample. Here's a sample implementation on returning the Subjects and Books from the Book sample database. First the stored proc:

CREATE PROCEDURE dbo.GetSubjectAndBooks
AS

 Select * from subject
 
 IF @@RowCount>0 BEGIN
  Select * from Book
 END

Now for the function mapping. We want to create a function that can return both the Subjects and the Books. To do this, we will create a function that returns the MultipleResult. Simlar to the standard stored procedure mapping, you create a function in a custom partial for the DataContext. The function will return a value of type IMultipleResults. Decorate the function with the FunctionAttribute including the name of the function. Here's the implementation in VB:

    <FunctionAttribute(Name:="dbo.GetSubjectAndBooks")> _
    <ResultType(GetType(Book))> _
    <ResultType(GetType(Subject))> _
    Public Function GetSubjectAndBooks() As IMultipleResults
        Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo))
        Dim results As IMultipleResults = DirectCast(result.ReturnValue, IMultipleResults)
        Return results
    End Function

Notice, the main difference here is the addition of two attributes identifying the possible ResultTypes (Book and Subject). The rest of the function should be self explanitory. To consume the function, we call the GetResult method of IMultipleResults passing in the generic type we want to return as follows:

    Dim context As New LinqBooksDataContext

    ObjectDumper.Write(context.GetSubjectAndBooks.GetResult(Of Subject))
    ObjectDumper.Write(context.GetSubjectAndBooks.GetResult(Of Book))

Posted on 1/9/2008 8:41:00 PM - Comments(4)
Categories: VB LINQ VB Dev Center
Comments:
  • Gravatar "Here we need to use the IMultipleResult rather than the default ISingleResult implementation. It appears that the designer does not map IMultipleResult in the final build, so we are going to need to do it ourselves. "



    How do you do that? Modify the generated code or modify the XML behind the dbml?
    Jeff Schwandt (Posted on 2/13/2009 10:01:00 AM)
  • Gravatar It's a bad idea to modify the generated code since your changes will be lost next time the code is regenerated. You're best of adding new functionality in a partial class on a new code file.
    Wole Ogunremi (Posted on 9/14/2009 1:04:00 AM)
  • Gravatar Wole,



    You are correct. The code you hand craft should be placed in a separate partial class file for the data context, not in the generated .designer file. Any changes you make to the .designer file will be overwritten if you modify the design surface at all.
    Jim (Posted on 9/14/2009 10:10:00 PM)
  • Gravatar Pingback from http://programmersgoodies.com/load-dataset-via-linq-to-sql
    Pingback (Posted on 9/16/2011 1:40:00 AM)