Skip to content

Commit

Permalink
Fix OData#530 LINQ query generation with Date functions produces weir…
Browse files Browse the repository at this point in the history
…d urls
  • Loading branch information
donchak committed Feb 11, 2018
1 parent ab32e8a commit d32f464
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
42 changes: 39 additions & 3 deletions src/Microsoft.OData.Client/ALinq/TypeSystem.cs
Expand Up @@ -53,7 +53,7 @@ internal static class TypeSystem
static TypeSystem()
{
#if !PORTABLELIB
const int ExpectedCount = 35;
const int ExpectedCount = 43;
#endif
// string functions
expressionMethodMap = new Dictionary<MethodInfo, string>(EqualityComparer<MethodInfo>.Default);
Expand All @@ -80,14 +80,24 @@ static TypeSystem()
expressionMethodMap.Add(typeof(TimeOfDay).GetProperty("Minutes", typeof(int)).GetGetMethod(), @"minute");
expressionMethodMap.Add(typeof(TimeOfDay).GetProperty("Seconds", typeof(int)).GetGetMethod(), @"second");

// datetimeoffset methods (date? time?)
// datetimeoffset methods
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Date", typeof(DateTime)).GetGetMethod(), @"date");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Day", typeof(int)).GetGetMethod(), @"day");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Hour", typeof(int)).GetGetMethod(), @"hour");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Month", typeof(int)).GetGetMethod(), @"month");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Minute", typeof(int)).GetGetMethod(), @"minute");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Second", typeof(int)).GetGetMethod(), @"second");
expressionMethodMap.Add(typeof(DateTimeOffset).GetProperty("Year", typeof(int)).GetGetMethod(), @"year");

// datetime methods
expressionMethodMap.Add(typeof(DateTime).GetProperty("Date", typeof(DateTime)).GetGetMethod(), @"date");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Day", typeof(int)).GetGetMethod(), @"day");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Hour", typeof(int)).GetGetMethod(), @"hour");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Month", typeof(int)).GetGetMethod(), @"month");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Minute", typeof(int)).GetGetMethod(), @"minute");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Second", typeof(int)).GetGetMethod(), @"second");
expressionMethodMap.Add(typeof(DateTime).GetProperty("Year", typeof(int)).GetGetMethod(), @"year");

// timespan methods
expressionMethodMap.Add(typeof(TimeSpan).GetProperty("Hours", typeof(int)).GetGetMethod(), @"hour");
expressionMethodMap.Add(typeof(TimeSpan).GetProperty("Minutes", typeof(int)).GetGetMethod(), @"minute");
Expand Down Expand Up @@ -144,6 +154,9 @@ static TypeSystem()
propertiesAsMethodsMap.Add(
typeof(DateTimeOffset).GetProperty("Day", typeof(int)),
typeof(DateTimeOffset).GetProperty("Day", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTimeOffset).GetProperty("Date", typeof(DateTime)),
typeof(DateTimeOffset).GetProperty("Date", typeof(DateTime)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTimeOffset).GetProperty("Hour", typeof(int)),
typeof(DateTimeOffset).GetProperty("Hour", typeof(int)).GetGetMethod());
Expand All @@ -159,6 +172,29 @@ static TypeSystem()
propertiesAsMethodsMap.Add(
typeof(DateTimeOffset).GetProperty("Year", typeof(int)),
typeof(DateTimeOffset).GetProperty("Year", typeof(int)).GetGetMethod());

propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Day", typeof(int)),
typeof(DateTime).GetProperty("Day", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Date", typeof(DateTime)),
typeof(DateTime).GetProperty("Date", typeof(DateTime)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Hour", typeof(int)),
typeof(DateTime).GetProperty("Hour", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Minute", typeof(int)),
typeof(DateTime).GetProperty("Minute", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Second", typeof(int)),
typeof(DateTime).GetProperty("Second", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Month", typeof(int)),
typeof(DateTime).GetProperty("Month", typeof(int)).GetGetMethod());
propertiesAsMethodsMap.Add(
typeof(DateTime).GetProperty("Year", typeof(int)),
typeof(DateTime).GetProperty("Year", typeof(int)).GetGetMethod());

propertiesAsMethodsMap.Add(
typeof(TimeSpan).GetProperty("Hours", typeof(int)),
typeof(TimeSpan).GetProperty("Hours", typeof(int)).GetGetMethod());
Expand Down Expand Up @@ -189,7 +225,7 @@ static TypeSystem()
typeof(Date).GetProperty("Day", typeof(int)),
typeof(Date).GetProperty("Day", typeof(int)).GetGetMethod());

Debug.Assert(propertiesAsMethodsMap.Count == 16, "propertiesAsMethodsMap.Count == 16");
Debug.Assert(propertiesAsMethodsMap.Count == 24, "propertiesAsMethodsMap.Count == 24");
}

/// <summary>
Expand Down
Expand Up @@ -34,6 +34,10 @@ public class DateTimeClientSupportTest
""value"":[{""Id"":""0001-01-01T00:00:00Z""},{""Id"":""2016-11-29T18:07:16-08:00""}],
""@odata.nextLink"":""EdmDateTimeSet?$skiptoken=2016-11-02T16%3A08%3A16-08%3A00""}";

const string FeedEntityPayloadWithDateTimeResponseSingleResult = @"{
""@odata.context"":""http://odataService/$metadata#EdmDateTimeSet"",
""value"":[{""Id"":""0001-01-01T00:00:00Z""}]}";

const string ReturnCollectionResponse = @"{
""@odata.context"":""http://odataService/$metadata#EdmDateTimeSet(0001-01-01T00%3A00%3A00Z)/DateTimeCollection"",
""value"":[""0001-01-01T00:00:00Z"",""2016-11-29T18:07:16-08:00"",""9999-12-31T23:59:59.9999999Z""]
Expand Down Expand Up @@ -61,6 +65,25 @@ public class DateTimeClientSupportTest
}";
private DateTime fixedDateTimeUtc = new DateTime(2016, 11, 30, 02, 07, 16, DateTimeKind.Utc);

[TestMethod]
public void TestClientLibDateTimeSupportGetDate()
{
TestDateTime(FeedEntityPayloadWithDateTimeResponseSingleResult, () =>
{
var queryResult = ((DataServiceQuery<pkr.EdmDateTime>)dsc_dateTime.EdmDateTimeSet.Where(e => e.Id.Date == (DateTime.MinValue)));
var result = queryResult.ToArray();
Assert.AreEqual(1, result.Count(), "Expected a single result");
Assert.AreEqual(result[0].Id, DateTime.MinValue);
});
TestDateTime(FeedEntityPayloadWithDateTimeResponseSingleResult, () =>
{
var queryResult = ((DataServiceQuery<pkr.EdmDateTime>)dsc_dateTime.EdmDateTimeSet.Where(e => e.Id.Date.Hour == 0));
var result = queryResult.ToArray();
Assert.AreEqual(1, result.Count(), "Expected a single result");
Assert.AreEqual(result[0].Id, DateTime.MinValue);
});
}

[TestMethod]
public void TestClientLibDateTimeSupport()
{
Expand Down
Expand Up @@ -891,6 +891,28 @@ public void WhereClauseWithMSecondsOfDateTimeOffsetShouldReturnUrlWithSecondFunc

Assert.AreEqual(rootUrl + "Test?$filter=second(timeOfDayProperty) ne 59", query);
}
[TestMethod]
public void WhereClauseWithDateOfDateTimeOffsetShouldReturnUrlWithDateFunction()
{
query = context.CreateQuery<EntityWithDateAndTime>("Test").Where(p => p.dateTimeOffsetProperty.Date == (DateTime.MinValue)).ToString();

Assert.AreEqual(rootUrl + "Test?$filter=date(dateTimeOffsetProperty) eq 0001-01-01T00:00:00Z", query);
}
[TestMethod]
public void WhereClauseWithDateAndHourOfDateTimeOffsetShouldReturnUrlWithDateAndHourFunctions()
{
query = context.CreateQuery<EntityWithDateAndTime>("Test").Where(p => p.dateTimeOffsetProperty.Date.Hour == 12).ToString();

Assert.AreEqual(rootUrl + "Test?$filter=hour(date(dateTimeOffsetProperty)) eq 12", query);
}
[TestMethod]
public void WhereClauseWithDateAndYearOfDateTimeOffsetShouldReturnUrlWithDateAndYearFunctions()
{
query = context.CreateQuery<EntityWithDateAndTime>("Test").Where(p => p.dateTimeOffsetProperty.Date.Year == 2014).ToString();

Assert.AreEqual(rootUrl + "Test?$filter=year(date(dateTimeOffsetProperty)) eq 2014", query);
}

#endregion
}
}

0 comments on commit d32f464

Please sign in to comment.