Skip to content

Commit 02fc529

Browse files
authored
Fix OData filtering by a base class member (#2387)
1 parent 7468a00 commit 02fc529

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

src/NHibernate.Test/Async/Linq/ODataTests.cs

+24
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,28 @@ public async Task OrderGroupByAsync(string queryString, int expectedRows)
6565
Assert.That(results, Has.Count.EqualTo(expectedRows));
6666
}
6767

68+
private class CustomerVm : BaseCustomerVm
69+
{
70+
}
71+
72+
private class BaseCustomerVm
73+
{
74+
public string Id { get; set; }
75+
76+
public string Name { get; set; }
77+
}
78+
79+
[TestCase("$filter=Name eq 'Maria Anders'", 1)]
80+
public async Task BasePropertyFilterAsync(string queryString, int expectedRows)
81+
{
82+
var query = ApplyFilter(
83+
session.Query<Customer>().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}),
84+
queryString);
85+
86+
var results = await (((IQueryable<CustomerVm>) query).ToListAsync());
87+
Assert.That(results, Has.Count.EqualTo(expectedRows));
88+
}
89+
6890
private IQueryable ApplyFilter<T>(IQueryable<T> query, string queryString)
6991
{
7092
var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { };
@@ -143,6 +165,8 @@ private static IEdmModel CreatEdmModel()
143165
employeeModel.EntityType.Property(o => o.Title);
144166
employeeModel.EntityType.HasMany(o => o.Orders);
145167

168+
builder.EntitySet<CustomerVm>(nameof(CustomerVm));
169+
146170
return builder.GetEdmModel();
147171
}
148172

src/NHibernate.Test/Linq/ODataTests.cs

+24
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ public void OrderGroupBy(string queryString, int expectedRows)
5353
Assert.That(results, Has.Count.EqualTo(expectedRows));
5454
}
5555

56+
private class CustomerVm : BaseCustomerVm
57+
{
58+
}
59+
60+
private class BaseCustomerVm
61+
{
62+
public string Id { get; set; }
63+
64+
public string Name { get; set; }
65+
}
66+
67+
[TestCase("$filter=Name eq 'Maria Anders'", 1)]
68+
public void BasePropertyFilter(string queryString, int expectedRows)
69+
{
70+
var query = ApplyFilter(
71+
session.Query<Customer>().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}),
72+
queryString);
73+
74+
var results = ((IQueryable<CustomerVm>) query).ToList();
75+
Assert.That(results, Has.Count.EqualTo(expectedRows));
76+
}
77+
5678
private IQueryable ApplyFilter<T>(IQueryable<T> query, string queryString)
5779
{
5880
var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { };
@@ -131,6 +153,8 @@ private static IEdmModel CreatEdmModel()
131153
employeeModel.EntityType.Property(o => o.Title);
132154
employeeModel.EntityType.HasMany(o => o.Orders);
133155

156+
builder.EntitySet<CustomerVm>(nameof(CustomerVm));
157+
134158
return builder.GetEdmModel();
135159
}
136160

src/NHibernate/Linq/NhLinqExpression.cs

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public IASTNode Translate(ISessionFactoryImplementor sessionFactory, bool filter
8787

8888
var requiredHqlParameters = new List<NamedParameterDescriptor>();
8989
var queryModel = NhRelinqQueryParser.Parse(_expression);
90+
queryModel.TransformExpressions(TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers);
9091
var visitorParameters = new VisitorParameters(sessionFactory, _constantToParameterMap, requiredHqlParameters,
9192
new QuerySourceNamer(), TargetType, QueryMode);
9293

src/NHibernate/Linq/Visitors/TransparentIdentifierRemovingExpressionVisitor.cs

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

0 commit comments

Comments
 (0)