diff --git a/src/NHibernate.Test/Async/Linq/ODataTests.cs b/src/NHibernate.Test/Async/Linq/ODataTests.cs index 0f794fdae88..44135195c13 100644 --- a/src/NHibernate.Test/Async/Linq/ODataTests.cs +++ b/src/NHibernate.Test/Async/Linq/ODataTests.cs @@ -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().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}), + queryString); + + var results = await (((IQueryable) query).ToListAsync()); + Assert.That(results, Has.Count.EqualTo(expectedRows)); + } + private IQueryable ApplyFilter(IQueryable query, string queryString) { var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { }; @@ -143,6 +165,8 @@ private static IEdmModel CreatEdmModel() employeeModel.EntityType.Property(o => o.Title); employeeModel.EntityType.HasMany(o => o.Orders); + builder.EntitySet(nameof(CustomerVm)); + return builder.GetEdmModel(); } diff --git a/src/NHibernate.Test/Linq/ODataTests.cs b/src/NHibernate.Test/Linq/ODataTests.cs index 7ac2a90cda7..572392110c4 100644 --- a/src/NHibernate.Test/Linq/ODataTests.cs +++ b/src/NHibernate.Test/Linq/ODataTests.cs @@ -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().Select(o => new CustomerVm {Name = o.ContactName, Id = o.CustomerId}), + queryString); + + var results = ((IQueryable) query).ToList(); + Assert.That(results, Has.Count.EqualTo(expectedRows)); + } + private IQueryable ApplyFilter(IQueryable query, string queryString) { var context = new ODataQueryContext(CreatEdmModel(), typeof(T), null) { }; @@ -131,6 +153,8 @@ private static IEdmModel CreatEdmModel() employeeModel.EntityType.Property(o => o.Title); employeeModel.EntityType.HasMany(o => o.Orders); + builder.EntitySet(nameof(CustomerVm)); + return builder.GetEdmModel(); } diff --git a/src/NHibernate/Linq/NhLinqExpression.cs b/src/NHibernate/Linq/NhLinqExpression.cs index 817bfe459e2..ad39397fd71 100644 --- a/src/NHibernate/Linq/NhLinqExpression.cs +++ b/src/NHibernate/Linq/NhLinqExpression.cs @@ -87,6 +87,7 @@ public IASTNode Translate(ISessionFactoryImplementor sessionFactory, bool filter var requiredHqlParameters = new List(); var queryModel = NhRelinqQueryParser.Parse(_expression); + queryModel.TransformExpressions(TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers); var visitorParameters = new VisitorParameters(sessionFactory, _constantToParameterMap, requiredHqlParameters, new QuerySourceNamer(), TargetType, QueryMode); diff --git a/src/NHibernate/Linq/Visitors/TransparentIdentifierRemovingExpressionVisitor.cs b/src/NHibernate/Linq/Visitors/TransparentIdentifierRemovingExpressionVisitor.cs index a2901b4068d..7016438e321 100644 --- a/src/NHibernate/Linq/Visitors/TransparentIdentifierRemovingExpressionVisitor.cs +++ b/src/NHibernate/Linq/Visitors/TransparentIdentifierRemovingExpressionVisitor.cs @@ -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. /// /// Replaces expression patterns of the form new T { x = 1, y = 2 }.x () or /// new T ( x = 1, y = 2 ).x () to 1 (or 2 if y is accessed instead of x).