Skip to content

Commit

Permalink
Merge pull request #13 from ZEXSM/bugfix/operator-in-and-bool-value
Browse files Browse the repository at this point in the history
* bugfix filter operator in 
* bugfix filter bool value
  • Loading branch information
ZEXSM authored Jul 31, 2019
2 parents cd71feb + 93c46da commit 0c88ed0
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 38 deletions.
61 changes: 30 additions & 31 deletions src/OData.QueryBuilder/Extensions/ExpressionExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,23 @@ public static string ToODataOperator(this ExpressionType expressionType)
}
}

public static string ToODataQuery(this ConstantExpression constantExpression) =>
constantExpression.Value?.ToString() ?? "null";
public static string ToODataQuery(this ConstantExpression constantExpression)
{
switch (constantExpression.Value)
{
case true:
return "true";
case false:
return "false";
case null:
return "null";
default:
return constantExpression.Value.ToString();
}
}

public static string ToODataQuery(this UnaryExpression unaryExpression) =>
((MemberExpression)unaryExpression.Operand).Member.Name;
(unaryExpression.Operand as MemberExpression)?.Member.Name;

public static string ToODataQuery(this MemberExpression memberExpression) =>
memberExpression.Member.Name;
Expand Down Expand Up @@ -182,44 +194,31 @@ public static string ToODataQuery(this Expression expression, string queryString
if (methodName == nameof(Enumerable.Contains))
{
var resource = default(object);
var memberExpression = methodCallExpression.Arguments[0] as MemberExpression;
var filter = default(string);

if (methodCallExpression.Object is MemberExpression)
if (methodCallExpression.Object == default(Expression))
{
resource = (methodCallExpression.Arguments[0] as MemberExpression).GetMemberExpressionValue();
filter = methodCallExpression.Arguments[1].ToODataQuery(queryString);
}
else if (methodCallExpression.Object is MemberExpression)
{
resource = (methodCallExpression.Object as MemberExpression).GetMemberExpressionValue();

var filter = memberExpression.ToODataQuery(queryString);

if (resource is IEnumerable<int>)
{
return $"{filter} in ({string.Join(",", (IEnumerable<int>)resource)})";
}

if (resource is IEnumerable<string>)
{
return $"{filter} in ('{string.Join("','", (IEnumerable<string>)resource)}')";
}
filter = methodCallExpression.Arguments[0].ToODataQuery(queryString);
}

if (memberExpression.Expression is MemberExpression)
if (resource is IEnumerable<int>)
{
resource = GetMemberExpressionValue(memberExpression);

var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString);

if (resource is IEnumerable<int>)
{
return $"{filter} in ({string.Join(",", (IEnumerable<int>)resource)})";
}
return $"{filter} in ({string.Join(",", (IEnumerable<int>)resource)})";
}

if (resource is IEnumerable<string>)
{
return $"{filter} in ('{string.Join("','", (IEnumerable<string>)resource)}')";
}
if (resource is IEnumerable<string>)
{
return $"{filter} in ('{string.Join("','", (IEnumerable<string>)resource)}')";
}
}

return $"{methodName.ToLower()}()";
return methodName.ToLower();

case NewExpression newExpression:
return newExpression.ToODataQuery();
Expand Down
2 changes: 2 additions & 0 deletions test/OData.QueryBuilder.Test/Fakes/ODataKindEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ public class ODataKindEntity
public ODataCodeEntity[] ODataCodes { get; set; }

public IEnumerable<int> Sequence { get; set; }

public int[] SequenceArray { get; set; }
}
}
6 changes: 6 additions & 0 deletions test/OData.QueryBuilder.Test/Fakes/ODataTypeEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ public class ODataTypeEntity

public decimal Sum { get; set; }

public bool IsActive { get; set; }

public bool IsOpen { get; set; }

public DateTime Open { get; set; }

public DateTime? BeginDate { get; set; }

public DateTimeOffset OpenDate { get; set; }

public ODataKindEntity ODataKind { get; set; }
Expand Down
35 changes: 28 additions & 7 deletions test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,28 +178,49 @@ public void ODataQueryBuilderList_Function_Date_Success()
&& s.Open == DateTime.Today
&& s.Open == constCurrentDateToday
&& s.Open.Date == newObject.ODataKind.EndDate
&& s.ODataKind.OpenDate.Date == new DateTime(2019, 7, 9))
&& s.ODataKind.OpenDate.Date == new DateTime(2019, 7, 9)
&& ((DateTime)s.BeginDate).Date == DateTime.Today)
.ToUri();

uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=date(ODataKind/OpenDate) eq 2019-02-09 and ODataKind/OpenDate eq 2019-02-09T00:00:00.0000000 and ODataKind/OpenDate eq {DateTime.Today.ToString("O")} and date(Open) eq {DateTime.Today.ToString("yyyy-MM-dd")} and Open eq {DateTime.Today.ToString("O")} and Open eq 2019-02-09T00:00:00.0000000 and date(Open) eq 2019-02-09 and date(ODataKind/OpenDate) eq 2019-07-09");
uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=date(ODataKind/OpenDate) eq 2019-02-09 and ODataKind/OpenDate eq 2019-02-09T00:00:00.0000000 and ODataKind/OpenDate eq {DateTime.Today.ToString("O")} and date(Open) eq {DateTime.Today.ToString("yyyy-MM-dd")} and Open eq {DateTime.Today.ToString("O")} and Open eq 2019-02-09T00:00:00.0000000 and date(Open) eq 2019-02-09 and date(ODataKind/OpenDate) eq 2019-07-09 and date(BeginDate) eq {DateTime.Today.ToString("yyyy-MM-dd")}");
}

[Fact(DisplayName = "(ODataQueryBuilderList) Operator IN => Success")]
public void ODataQueryBuilderList_Operator_In_Success()
{
var constStrIds = new[] { "123", "512" }.ToList();
var constIntIds = new[] { 123, 512 }.ToList();
var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntIds } };
var constStrIds = new[] { "123", "512" };
var constStrListIds = new[] { "123", "512" }.ToList();
var constIntIds = new[] { 123, 512 };
var constIntListIds = new[] { 123, 512 }.ToList();
var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } };
var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } };

var uri = _odataQueryBuilder
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
.Filter(s => constStrIds.Contains(s.ODataKind.ODataCode.Code)
&& constStrListIds.Contains(s.ODataKind.ODataCode.Code)
&& constIntIds.Contains(s.IdType)
&& newObject.ODataKind.Sequence.Contains(s.IdType))
&& constIntListIds.Contains(s.IdType)
&& constIntIds.Contains((int)s.IdRule)
&& constIntListIds.Contains((int)s.IdRule)
&& newObject.ODataKind.Sequence.Contains(s.ODataKind.IdKind)
&& newObjectSequenceArray.ODataKind.SequenceArray.Contains(s.ODataKind.ODataCode.IdCode))
.ToUri();

uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512)");
uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512)");
}

[Fact(DisplayName = "(ODataQueryBuilderList) Filter boolean values => Success")]
public void ODataQueryBuilderList_Filter_Boolean_Values_Success()
{
var uri = _odataQueryBuilder
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
.Filter(s => s.IsActive && s.IsOpen == true && s.ODataKind.ODataCode.IdActive == false)
.ToUri();

uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IsActive and IsOpen eq true and ODataKind/ODataCode/IdActive eq false");
}
}
}

0 comments on commit 0c88ed0

Please sign in to comment.