Skip to content
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

Implemented 'ODataPropertyName' attribute #117

Merged
merged 6 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/OData.QueryBuilder/Attributes/ODataPropertyNameAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace OData.QueryBuilder.Attributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class ODataPropertyNameAttribute : Attribute

Check warning on line 6 in src/OData.QueryBuilder/Attributes/ODataPropertyNameAttribute.cs

View workflow job for this annotation

GitHub Actions / build&test&coverage(ubuntu-latest)

Missing XML comment for publicly visible type or member 'ODataPropertyNameAttribute'
{
public string Name;

Check warning on line 8 in src/OData.QueryBuilder/Attributes/ODataPropertyNameAttribute.cs

View workflow job for this annotation

GitHub Actions / build&test&coverage(ubuntu-latest)

Missing XML comment for publicly visible type or member 'ODataPropertyNameAttribute.Name'

public ODataPropertyNameAttribute(string name)
{
Name = name;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using OData.QueryBuilder.Extensions;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using OData.QueryBuilder.Attributes;

namespace OData.QueryBuilder.Expressions.Visitors
{
Expand Down Expand Up @@ -53,7 +55,7 @@ protected virtual string VisitMethodCallExpression(LambdaExpression topExpressio
if (genericMethodType != memberExpression.Type)
throw new ArgumentException(
$"The type '{genericMethodType.FullName}' specified when calling 'ODataProperty.FromPath<T>(\"{propertyPath}\")' does not match the expected type '{memberExpression.Type.FullName}' defined by the model.");

return VisitMemberExpression(topExpression, memberExpression);
}
}
Expand All @@ -78,15 +80,22 @@ protected virtual string VisitMemberExpression(LambdaExpression topExpression, M
{
var memberName = VisitExpression(topExpression, memberExpression.Expression);

var reflectedMemberName = memberExpression.Member.Name;
var propertyNameAttribute = memberExpression.Member.GetCustomAttribute<ODataPropertyNameAttribute>();
if (propertyNameAttribute != null)
{
reflectedMemberName = propertyNameAttribute.Name;
}

if (string.IsNullOrEmpty(memberName))
{
return memberExpression.Member.Name;
return reflectedMemberName;
}

return memberExpression.Member.DeclaringType.IsNullableType() ?
memberName
:
$"{memberName}/{memberExpression.Member.Name}";
$"{memberName}/{reflectedMemberName}";
}

public virtual string ToQuery(LambdaExpression expression) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
</Project>

<ItemGroup>
<ProjectReference Include="..\..\src\OData.QueryBuilder\OData.QueryBuilder.csproj" />
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions test/OData.QueryBuilder.Fakes/ODataKindEntity.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using OData.QueryBuilder.Attributes;

namespace OData.QueryBuilder.Fakes
{
Expand All @@ -23,5 +24,8 @@ public class ODataKindEntity
public long[] SequenceLongArray { get; set; }

public ColorEnum Color { get; set; }

[ODataPropertyName("customName")]
public string CustomNamedProperty { get; set; }
}
}
70 changes: 36 additions & 34 deletions test/OData.QueryBuilder.Test/ODataQueryCollectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public void ODataQueryBuilderList_Expand_DynamicProperty_Success()
.ToUri();

uri.Should().Be("http://mock/odata/ODataType?$expand=ODataKind");
}
}

[Fact(DisplayName = "Select simple => Success")]
public void ODataQueryBuilderList_Select_Simple_Success()
{
Expand All @@ -69,8 +69,8 @@ public void ODataQueryBuilderList_Select_DynamicProperty_Success()
.ToUri();

uri.Should().Be("http://mock/odata/ODataType?$select=IdType");
}
}

[Fact(DisplayName = "OrderBy simple => Success")]
public void ODataQueryBuilderList_OrderBy_Simple_Success()
{
Expand All @@ -93,8 +93,8 @@ public void ODataQueryBuilderList_OrderBy_DynamicProperty_Success()
.ToUri();

uri.Should().Be("http://mock/odata/ODataType?$orderby=IdType asc");
}
}

[Fact(DisplayName = "Filter orderBy multiple sort => Success")]
public void ODataQueryBuilderList_Filter_OrderBy_Multiple_Sort_Success()
{
Expand Down Expand Up @@ -354,8 +354,8 @@ public void ODataQueryBuilderList_Filter_With_ReplaceCharacters_KeyValuePairs_Ar
[Fact(DisplayName = "Filter variable dynamic property int=> Success")]
public void ODataQueryBuilderList_Filter_Simple_Variable_DynamicProperty_Success()
{
string propertyName = "ODataKind.ODataCode.IdCode";
string propertyName = "ODataKind.ODataCode.IdCode";

var uri = _odataQueryBuilderDefault
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
Expand All @@ -376,8 +376,8 @@ public void ODataQueryBuilderList_Filter_Simple_Variable_DynamicProperty_WrongTy
.ByList()
.Filter((s, f, _) => ODataProperty.FromPath<string>(propertyName) == "test")
.ToUri()).Should().Throw<ArgumentException>();
}
}

[Fact(DisplayName = "Filter const dynamic property int=> Success")]
public void ODataQueryBuilderList_Filter_Simple_Const_DynamicProperty_Success()
{
Expand All @@ -388,8 +388,8 @@ public void ODataQueryBuilderList_Filter_Simple_Const_DynamicProperty_Success()
.ToUri();

uri.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/IdCode ge 3");
}
}

[Fact(DisplayName = "Filter simple const int=> Success")]
public void ODataQueryBuilderList_Filter_Simple_Const_Int_Success()
{
Expand Down Expand Up @@ -576,6 +576,7 @@ public void ODataQueryBuilderList_Function_Date_Success()
&& s.ODataKind.OpenDate == currentDateToday
&& s.ODataKind.OpenDate == DateTime.Today
&& s.ODataKind.OpenDate == new DateTimeOffset()
&& s.ODataKind.CustomNamedProperty == "test"
&& s.Open == new DateTime()
&& f.Date(s.Open) == DateTime.Today
&& f.Date(s.Open) == DateTimeOffset.Now
Expand All @@ -592,6 +593,7 @@ public void ODataQueryBuilderList_Function_Date_Success()
$"and ODataKind/OpenDate eq 2019-02-09T00:00:00Z " +
$"and ODataKind/OpenDate eq {DateTime.Today:s}Z " +
$"and ODataKind/OpenDate eq {new DateTimeOffset():s}Z " +
$"and ODataKind/customName eq 'test' " +
$"and Open eq {new DateTime():s}Z " +
$"and date(Open) eq {DateTime.Today:s}Z " +
$"and date(Open) eq {DateTimeOffset.Now:s}Z " +
Expand Down Expand Up @@ -1560,39 +1562,39 @@ public void ODataQueryBuilder_Function_Cast_Skip_Exception(string value)
.ToUri();

uri.Should().Be("http://mock/odata/ODataType?$filter=contains(,'55')");
}
}

[Fact(DisplayName = "UseCorrectDateTimeFormat Convert => Success")]
public void ODataQueryBuilderList_UseCorrectDatetimeFormat_Convert_Success()
{
var builder = new ODataQueryBuilder<ODataInfoContainer>(
_commonFixture.BaseUri,
new ODataQueryBuilderOptions { UseCorrectDateTimeFormat = true });
var dateTimeLocal = new DateTime(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, kind: DateTimeKind.Local);
var dateTimeUtc = new DateTime(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, kind: DateTimeKind.Utc);
var dateTimeOffset = new DateTimeOffset(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, offset: TimeSpan.FromHours(+7));
var dateTimeOffset2 = new DateTimeOffset(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, offset: TimeSpan.FromHours(-7));
{
var builder = new ODataQueryBuilder<ODataInfoContainer>(
_commonFixture.BaseUri,
new ODataQueryBuilderOptions { UseCorrectDateTimeFormat = true });

var dateTimeLocal = new DateTime(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, kind: DateTimeKind.Local);
var dateTimeUtc = new DateTime(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, kind: DateTimeKind.Utc);
var dateTimeOffset = new DateTimeOffset(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, offset: TimeSpan.FromHours(+7));
var dateTimeOffset2 = new DateTimeOffset(
year: 2023, month: 04, day: 07, hour: 12, minute: 30, second: 20, offset: TimeSpan.FromHours(-7));
var nowOffset = $"{DateTimeOffset.Now:zzz}".Replace("+", "%2B");

var uri = builder
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
.Filter((o) =>
o.DateTime == dateTimeLocal
&& o.DateTime == dateTimeUtc
&& o.DateTime == dateTimeOffset
.Filter((o) =>
o.DateTime == dateTimeLocal
&& o.DateTime == dateTimeUtc
&& o.DateTime == dateTimeOffset
&& o.DateTime == dateTimeOffset2)
.ToUri();

uri.Should().Be($"http://mock/odata/ODataType?$filter=" +
$"DateTime eq 2023-04-07T12:30:20{nowOffset} and " +
$"DateTime eq 2023-04-07T12:30:20%2B00:00 and " +
$"DateTime eq 2023-04-07T12:30:20%2B07:00 and " +
$"DateTime eq 2023-04-07T12:30:20{nowOffset} and " +
$"DateTime eq 2023-04-07T12:30:20%2B00:00 and " +
$"DateTime eq 2023-04-07T12:30:20%2B07:00 and " +
$"DateTime eq 2023-04-07T12:30:20-07:00");
}
}
Expand Down
Loading