Skip to content

Commit

Permalink
Fix OData filtering by a base class member (#2387)
Browse files Browse the repository at this point in the history
  • Loading branch information
maca88 authored May 19, 2020
1 parent 7468a00 commit 02fc529
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/NHibernate.Test/Async/Linq/ODataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ public async Task OrderGroupByAsync(string queryString, int expectedRows)
Assert.That(results, Has.Count.EqualTo(expectedRows));
}

private class CustomerVm : BaseCustomerVm
{
}

private class BaseCustomerVm
{
public string Id { get; set; }

public string Name { get; set; }
}

[TestCase("$filter=Name eq 'Maria Anders'", 1)]
public async Task BasePropertyFilterAsync(string queryString, int expectedRows)
{
var query = ApplyFilter(
session.Query<Customer>().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}),
queryString);

var results = await (((IQueryable<CustomerVm>) query).ToListAsync());
Assert.That(results, Has.Count.EqualTo(expectedRows));
}

private IQueryable ApplyFilter<T>(IQueryable<T> query, string queryString)
{
var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { };
Expand Down Expand Up @@ -143,6 +165,8 @@ private static IEdmModel CreatEdmModel()
employeeModel.EntityType.Property(o => o.Title);
employeeModel.EntityType.HasMany(o => o.Orders);

builder.EntitySet<CustomerVm>(nameof(CustomerVm));

return builder.GetEdmModel();
}

Expand Down
24 changes: 24 additions & 0 deletions src/NHibernate.Test/Linq/ODataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ public void OrderGroupBy(string queryString, int expectedRows)
Assert.That(results, Has.Count.EqualTo(expectedRows));
}

private class CustomerVm : BaseCustomerVm
{
}

private class BaseCustomerVm
{
public string Id { get; set; }

public string Name { get; set; }
}

[TestCase("$filter=Name eq 'Maria Anders'", 1)]
public void BasePropertyFilter(string queryString, int expectedRows)
{
var query = ApplyFilter(
session.Query<Customer>().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}),
queryString);

var results = ((IQueryable<CustomerVm>) query).ToList();
Assert.That(results, Has.Count.EqualTo(expectedRows));
}

private IQueryable ApplyFilter<T>(IQueryable<T> query, string queryString)
{
var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { };
Expand Down Expand Up @@ -131,6 +153,8 @@ private static IEdmModel CreatEdmModel()
employeeModel.EntityType.Property(o => o.Title);
employeeModel.EntityType.HasMany(o => o.Orders);

builder.EntitySet<CustomerVm>(nameof(CustomerVm));

return builder.GetEdmModel();
}

Expand Down
1 change: 1 addition & 0 deletions src/NHibernate/Linq/NhLinqExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public IASTNode Translate(ISessionFactoryImplementor sessionFactory, bool filter

var requiredHqlParameters = new List<NamedParameterDescriptor>();
var queryModel = NhRelinqQueryParser.Parse(_expression);
queryModel.TransformExpressions(TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers);
var visitorParameters = new VisitorParameters(sessionFactory, _constantToParameterMap, requiredHqlParameters,
new QuerySourceNamer(), TargetType, QueryMode);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace NHibernate.Linq.Visitors
// Copied from Relinq and added a fallback for comparing two member info by DeclaringType and Name
// 6.0 TODO: drop if https://github.com/OData/WebApi/issues/2108 is fixed and add a possible breaking
// change requiring to upgrade OData. (See https://github.com/nhibernate/nhibernate-core/pull/2322#discussion_r401215456 )
// Use this version in order to support expressions that were created programmatically and do not mimic what the C# compiler generates.
// Consider removing this if https://re-motion.atlassian.net/projects/RMLNQ/issues/RMLNQ-121 is fixed and we upgrade ReLinq.
/// <summary>
/// Replaces expression patterns of the form <c>new T { x = 1, y = 2 }.x</c> (<see cref="MemberInitExpression"/>) or
/// <c>new T ( x = 1, y = 2 ).x</c> (<see cref="NewExpression"/>) to <c>1</c> (or <c>2</c> if <c>y</c> is accessed instead of <c>x</c>).
Expand Down

0 comments on commit 02fc529

Please sign in to comment.