locked
ObjectGraph Dilemma: Expand, LoadProperty and Service Operations. RRS feed

  • Question

  • I have a service operation called FindTelcos, however Expand does not work with it to drill into related objects. 

    Code Snippet

    var companies = (from x in Service.FindCompanies(search).Expand("Contacts")
                                           select x).ToList<Company>();

     

     

    The workaround is to use LoadProperty

     

    Code Snippet

    var companies = (from x in Service.FindCompanies(search)
                       select x).ToList<Company>();
    foreach (var c in companies)
    {

        Service.LoadProperty(c, "Contacts");

    }

     

    However my object graph doesn't stop there. I'd liked to do Service.LoadProperty(ts. "Contacts").Expand("Address.State") or even do the expand right on the FindCompanies(search).Expand("Contacts.Address.State").

     

    From what I can tell, I'll have to iterate over the Contacts and for each one do a LoadProperty on Address and on State as well. This is a really chatty interface. Any way to avoid this?

     

    Thanks

     

    Barry Gervin

    www.ObjectSharp.com/Barry

     


    Wednesday, August 6, 2008 3:36 PM

All replies

  •  

    Hi Barry,

     What is the signature of the ServiceOp FindCompanies ?
     Also , can you please check the URI that the client generates for :


     

    Code Snippet
    var companies = Service
      .FindCompanies(search)
      .Expand("Contacts")
      .ToList<Company>();

     

    You can break into the debugger and hover the "companies" variable to see the
     uri that the client generates for the query .
    once you have the URI, try the same in the browser to observe the results.
    We allow chaining of the results if the Service Op returns
    IQueryable where T is an Entity type.

    Wednesday, August 6, 2008 4:23 PM
    Moderator
  •  

    Thanks Phani,

     

    Thesignature of FindCompanies on the Proxy is

    Code Snippet

    public global::System.Data.Services.Client.DataServiceQuery FindCompanies(string search)

     

     

    and on the Service itself

    Code Snippet

    public IQueryable FindCompanies(string search)

    {

        var foundCompanies = this.CurrentDataSource.FindCompanies(search);

        return foundCompanies.AsQueryable();

    }

     

    The FindCompanies method on my ObjectContext is

    Code Snippet

    public global::System.Data.Objects.ObjectResult<Company> FindCompanies(string search)

     

    And it calls a stored procedure mapped in my EDMX.

     

    The URI is

    http://localhost/MyService/MyDataService.svc/FindCompanies()?$expand=Contacts&search='test'

     

    The Response is

    The remote server returned an error: (500) Internal Server Error.

     

    HTTP/1.1 500 Internal Server Error
    Date: Wed, 06 Aug 2008 22:30:02 GMT
    Server: Microsoft-IIS/6.0
    X-Powered-By: ASP.NET
    X-AspNet-Version: 2.0.50727
    Cache-Control: private
    Content-Type: text/plain
    Content-Length: 1645

    Exception has been thrown by the target of an invocation.
       at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Data.Services.Providers.ObjectContextServiceProvider.ApplyExpansions(IQueryable queryable, ICollection`1 expandPaths)
       at System.Data.Services.RequestQueryProcessor.ProcessExpand()
       at System.Data.Services.RequestQueryProcessor.ProcessQuery()
       at System.Data.Services.RequestQueryProcessor.ProcessQuery(IDataService service, RequestDescription description)
       at System.Data.Services.RequestUriProcessor.ProcessRequestUri(Uri absoluteRequestUri, IDataService service)
       at System.Data.Services.DataService`1.ProcessIncomingRequestUriAndCacheHeaders()
       at System.Data.Services.DataService`1.HandleRequest()
    Unable to cast object of type 'System.Linq.EnumerableQuery`1[SampleApp.Data.Company]' to type 'System.Data.Objects.ObjectQuery`1[SampleApp.Data.Company]'.
       at System.Data.Services.Providers.ObjectContextServiceProvider.Include[T](IQueryable query, String dottedPath)

    Wednesday, August 6, 2008 10:31 PM
  • Hi ,

     The error message is ::

     

    Unable to cast object of type 'System.Linq.EnumerableQuery`1[SampleApp.Data.Company]' to type 'System.Data.Objects.ObjectQuery`1[SampleApp.Data.Company]'.

     

    Change your ServiceOp to be :

     

    Code Snippet

    public IQueryable<SampleApp.Data.Company> FindCompanies(string search)

    {

        var foundCompanies = this.CurrentDataSource.FindCompanies(search);

        return foundCompanies.AsQueryable<SampleApp.Data.Company>();

    }

     

     

    This should work.

    Also , this link is helpful to understand which return types are valid :

     

    http://blogs.msdn.com/marcelolr/archive/2008/01/21/service-operations-in-ado-net-data-services.aspx
    Wednesday, August 6, 2008 10:53 PM
    Moderator
  • That got me past the error, but I'm faced with another error on this query:

     

    Object reference not set to an instance of an object.
       at lambda_method(ExecutionScope , Company )
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Data.Services.Providers.BasicExpandProvider.ExpandedEnumerator`2.MoveNext()
       at System.Data.Services.DataService`1.SerializeResponseBody(RequestDescription description, IDataService dataService)
       at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)
       at System.Data.Services.DataService`1.HandleRequest()
    
    Any ideas? I'm still running on the SP1 Beta 1. Any chance this will be fixed in RTM - or am I doing something wrong?
    Here's the URL
    http://localhost/root/MyDataService.svc/FindCompanies()?$expand=Address/State&search='ObjectSharp'
    and the query client side:
    Code Snippet
    var companies = (from x in Service.FindCompanies("ObjectSharp")
    .Expand("Address/State")
    select x).ToList<Company>();

     

     

     Thanks
    Saturday, August 9, 2008 4:20 PM