locked
Bug in DataServiceQuery.First method RRS feed

  • Question

  • It seems that there is a bug in DataServiceQuery.First method. Code 1 doesn’t work when I use First method, but when I use foreach loop and just take first element (code 2) it works. Fiddler trace for code 1 simply returns:

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>

    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">

      <code></code>

      <message xml:lang="en-US">Bad Request - Error in query syntax.</message>

    </error>

    Code 1:

    // Initialization

    ctx = new DataServiceContext(
                      new Uri("http://.../TestModelService.svc"));

                ctx.MergeOption = MergeOption.AppendOnly;

     

                DataServiceQuery<Course> qc =
                                  ctx.CreateQuery<Course>("Course(9)");

                Course cx = null;

     

                // Using DataServiceQuery.First

                try

                {

                    cx = qc.First<Course>();

                }

                catch (Exception e)

                {

                    Console.WriteLine(e);

                }

    Code 2:

    // Initialization

    ctx = new DataServiceContext(
                      new Uri("http://.../TestModelService.svc"));

                ctx.MergeOption = MergeOption.AppendOnly;

     

    DataServiceQuery<Course> qc = 

                      ctx.CreateQuery<Course>("Course(9)");

                Course cx = null;

     

                // Using foreach

                foreach (Course c in qc)

                {

                    cx = c;

                    break;

                }

    Thursday, October 9, 2008 7:47 AM

Answers

  • Two issues here =

     

    1)  It is unsupported to pass in anything other then a EntitySet name to CreateQuery and then call Linq operators.  it happens to work in some cases, but the Astoria client library does not parse the string and therefore doesn't know you are asking for a Singleton to be returned instead of a set.

     

    2)  When you call First from Linq, the Astoria client library translates this into a $top=1 query option.  Currently Astoria does not support query options (besides expand) on uris that return a single entity.  Hence why you are getting a bad request error returned from the server.

     

    Hope that helps.

     

     

    Thursday, October 9, 2008 4:33 PM
    Moderator
  • Dear Andrew,

     

    Thank you for your explanation. Anyway I hope that you will support this scenario soon. It is pretty natural use case and I don’t see any reason why it shouldn’t work (except technical ones). Till that moment here is elegant way to get just one element (when id is known):

     

    DataServiceQuery<Course> qs = ctx.CreateQuery<Course>("Course");

     

    Course cx = qs.Where<Course>(c => c.Id == 9).First<Course>();

     

    Friday, October 10, 2008 2:42 PM

All replies

  • Two issues here =

     

    1)  It is unsupported to pass in anything other then a EntitySet name to CreateQuery and then call Linq operators.  it happens to work in some cases, but the Astoria client library does not parse the string and therefore doesn't know you are asking for a Singleton to be returned instead of a set.

     

    2)  When you call First from Linq, the Astoria client library translates this into a $top=1 query option.  Currently Astoria does not support query options (besides expand) on uris that return a single entity.  Hence why you are getting a bad request error returned from the server.

     

    Hope that helps.

     

     

    Thursday, October 9, 2008 4:33 PM
    Moderator
  • I think there is a bug filed on this already.  First has issue with this also, so I am guessing maybe same issue:

     

    db.Users.First(u=>u.Name="wjs");  // Error

     

    db.Users.Where(...).First();  //Works.

    Thursday, October 9, 2008 11:21 PM
  • Actually using First with a predicate is currently not supported.

     

    Also, I am not sure what bug you are referring to.  As I said in my prior post, the example given is not a supported scenario with the Astoria client.  If you provide anything other then just the EntitySet Name when you call CreateQuery and then perform Linq operations the behavior is undefined.

     

     

    Friday, October 10, 2008 12:04 AM
    Moderator
  • Dear Andrew,

     

    Thank you for your explanation. Anyway I hope that you will support this scenario soon. It is pretty natural use case and I don’t see any reason why it shouldn’t work (except technical ones). Till that moment here is elegant way to get just one element (when id is known):

     

    DataServiceQuery<Course> qs = ctx.CreateQuery<Course>("Course");

     

    Course cx = qs.Where<Course>(c => c.Id == 9).First<Course>();

     

    Friday, October 10, 2008 2:42 PM