New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LINQ query generation with Date functions produces weird urls #530

Closed
nicenemo opened this Issue Apr 11, 2016 · 1 comment

Comments

Projects
None yet
4 participants
@nicenemo

nicenemo commented Apr 11, 2016

Question: LINQ query to url generation wrong when using Dates in where clauses?
Using the OData .NET client with LINQ queries and service implemented with OLingo.

Assemblies affected

OData .NET client lib 6.15-beta

Reproduce steps

Write a linq query with a where clause one a time stamp e.g.
where x.creationTime.hour >=0..

Expected result

Not sure if this a bug. Maybe another url should be generated or Or our service implementation is wrong.

Actual result

weird url with path in querystring is generated.
Malformed Url exception is thrown.

Additional details

The following two tests succeed in producing a wrong url:

/// <summary>
/// Using date function in a where clause does not work. The url generated is wrong.
/// </summary>
[Fact]
public void DocumentsDateHourGeZeroLinqDoesNotWork()
{

  var ctx = CreateContext();
  var fakedSessionIds = PostFakeSessions(ctx, 3);

  try
  {
    Action action = () =>  {var fakedDocuments = (from doc in ctx.Documents where doc.CreationDate.Value.Date.Hour >= 0 select doc).ToArray(); };
    Assert.Throws<DataServiceQueryException>(action);

  }
  finally
  {
    DeleteDocuments(ctx, fakedSessionIds);
  }
}

/// <summary>
/// Using date function in a where clause does not work. The url generated is wrong.
/// </summary>
[Fact]
public void DocumentsDateHourGeZeroNoLINQExpressionsDoesNotWork()
{
  var ctx = CreateContext();
  var fakedSessionIds = PostFakeSessions(ctx, 3);

  try
  {
    Action action = () => { var fakedDocuments = ctx.Documents.Where((doc) => doc.CreationDate.Value.Date.Hour >= 0).ToArray(); };

    Assert.Throws<DataServiceQueryException>(action);                 
  }
  finally
  {
    DeleteDocuments(ctx, fakedSessionIds);
  }
}

the url generated is:

https://server.example.com/odata/ODataServlet/Documents?$filter=creationDate/Date/Hour%20ge%200

The following test produces the right result:

    /// <summary>
    /// Using date function in hand crafted url does work
    /// </summary>
    [Fact]
    public void DocumentsDateHourGeZeroNoLINQ()
    {
      var ctx = CreateContext();
      var fakedSessions = PostFakeSessions(ctx, 3);

      try
      {
        const string path = "/odata/ODataServlet/Documents?$filter=hour(creationDate) ge 0";
        var uri = new Uri(Service.Default.host, path);

        var t = ctx.ExecuteAsync<DocumentContent>(uri, "GET");
        t.Wait();

        Assert.Equal(TaskStatus.RanToCompletion, t.Status);
        Assert.NotNull(t.Result);
        var documents = t.Result.ToArray();
        Assert.True(documents.Any());
        Assert.False((from doc in documents where doc.CreationDate.Value.Hour < 0 select doc).Any());

      }
      catch(AggregateException ex)
      {
        throw ex.InnerExceptions.FirstOrDefault();
      }
      finally
      {
        DeleteDocuments(ctx, fakedSessions);
      }
    }

The url generated is:
http://server.example.com/odata/ODataServlet/Documents?$filter=hour(creationDate)%20ge%200

@nicenemo

This comment has been minimized.

nicenemo commented Apr 11, 2016

Note: without Date in ... where doc.CreationDate.Value.Date.Hour >= 0 ... it does work.

    /// <summary>
    /// Using date function in a where clause that does generate a good url.
    /// </summary>
    [Fact]
    public void DocumentsDateTimeOfSetHourGeZeroLinqDoesWork()
    {

      var ctx = CreateContext();
      var fakedSessionIds = PostFakeSessions(ctx, 3);
      var hour = DateTime.Now.Hour;

      try
      {
       var fakedDocuments = (from doc in ctx.Documents where doc.CreationDate.Value.Hour >= hour select doc).ToArray();
        Assert.NotNull(fakedDocuments);
        Assert.NotEmpty(fakedDocuments);
        //With Date in between it does not work: Action action = () => { var fakedDocuments = (from doc in ctx.Documents where doc.CreationDate.Value.Date.Hour >= 0 select doc).ToArray(); };
      }
      finally
      {
        DeleteDocuments(ctx, fakedSessionIds);
      }
    }

@manivannanse manivannanse added the P4 label Jun 8, 2017

@robward-ms robward-ms removed the backlog label Sep 27, 2017

donchak added a commit to donchak/odata.net that referenced this issue Feb 1, 2018

@donchak donchak referenced this issue Feb 1, 2018

Closed

Odata v4 6.x - Fix #530 Fix #530 WRONG BRANCH #1062

2 of 2 tasks complete

donchak added a commit to donchak/odata.net that referenced this issue Feb 7, 2018

donchak added a commit to donchak/odata.net that referenced this issue Feb 7, 2018

@donchak donchak referenced this issue Feb 7, 2018

Closed

Odata v4 7.x - Fix #530 WRONG BRANCH #1066

2 of 2 tasks complete

donchak added a commit to donchak/odata.net that referenced this issue Feb 8, 2018

donchak added a commit to donchak/odata.net that referenced this issue Feb 8, 2018

donchak added a commit to donchak/odata.net that referenced this issue Feb 11, 2018

mikepizzo added a commit that referenced this issue Feb 14, 2018

@mikepizzo mikepizzo closed this in 9089507 Feb 14, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment