Search code examples
.netentity-frameworkwcf-data-servicesodata

Materializing a 'WCF Data Service' service operation that calls a Stored Procedure


The short of it:

Is there a way to materialize service operations that use Entity Framework, but do a stored procedure call instead of Linq to Entities?

The details:

I have an OData (WCF Data Service) that has several service operations in it. They all work fine.

Today I tried to add a new service operation and I cannot get it to work in LinqPad.

My new service operation is different from the others in that it calls a stored procedure (rather than using Linq To Entities).

It looks like this:

[WebGet]
public IQueryable<MySproc_Result> GetTheDataINeed(long id)
{
    return CurrentDataSource.MySproc(id).AsQueryable();
}

When I run this in LinqPad like this:

CreateQuery<MySproc_Result>"GetTheDataINeed").AddQueryOption("id", "91675L")

I get the following error:

Cannot materialize a collection of a primitives or complex without the type 'LINQPad.User.MySproc_Result' being a collection.

Note: I ran one of my other service operations using this syntax and it worked fine

I decided to see if it would run in a browser (as a url). I plugged both this and a working service operation into Internet Explorer.

The difference was easy to see right away:

Bad

<?xml version="1.0" encoding="UTF-8"?>
<GetTheDataINeed xmlns:m="namespace removed for brevity">
     <element m:type="MyModel.MySproc_Result">
        <SomeData>Data Goes Here</SomeData>
        <OtherData>Other Data Goes Here</OtherData>
        ...

Good

<?xml version="1.0" encoding="utf-8" ?> 
 <feed xml:base="http://localhost:26257/MyServiceHere.svc/" Other xmlns ommited>
  <id>http://localhost:26257/MyServiceHere.svc/ValidServiceOperation</id> 
  <title type="text">ValidServiceOperation</title> 
  <updated>2013-07-02T23:24:11Z</updated> 
  <link rel="self" title="ValidServiceOperation" href="ValidServiceOperation" /> 
    <entry>
        <id>http://localhost:26257/MyServiceHere.svc/Orders(156L)</id> 
        <category ... ommited /> 
        <link lots of links ommited /> 
        <title /> 
        <updated>2013-07-02T23:24:11Z</updated> 
        <author>
            <name /> 
        </author>
        <content type="application/xml">
            <m:properties>
                <d:SomeData m:type="Edm.Int64">Some Data Here</d:SomeData> 
                <d:OtherData m:type="Edm.DateTime">Other Data Here</d:OtherData>
                ...

The working one seems to have quite a bit of meta data that the non-working one is missing. I am guessing that is why the materializer failed. What I don't know is how to get my service operation that is calling a stored procedure to get that xml format.

Is there a way to materialize service operations that use Entity Framework, but do a stored procedure call?

NOTES:

  • I am running WCF Data Services 5.5.0 on both the server and the client and have install the 5.3.0 tooling.
  • I have tried running in a console app (to be sure that it is not just linqpad)
  • I have tried the following syntax as well, and it does not work:

    Execute<MySproc_Result>(new Uri("GetTheDataINeed?id=91675L", UriKind.Relative),
                            "GET" , false)
    

Solution

  • I had a problem very similar to this. The solution was to create a property within the DataContext which returned the type in question. To make that a little clearer, I had a method on the service like this:

        [WebGet()]
        public IQueryable<VolumeSlaReportSummary> GetVolumeSlaSummary(...)
        {
            ...
            return this.CurrentDataSource.GetVolumeSlaSummary(...);
        }
    

    When I called that method I got XML in the form <GetVolumeSlaSummary...., instead of the expected <feed...

    So, in the DataContext, I created a property like this:

        public IQueryable<VolumeSlaReportSummary> VolSlaSummary
        {
            get
            {
                return this.GetVolumeSlaSummary(...);
            }
        }
    

    Calling the method now returns the expected <feed... style XML.