diff --git a/src/Rdd.Domain/Helpers/Expressions/ExpressionParser.cs b/src/Rdd.Domain/Helpers/Expressions/ExpressionParser.cs index 2cdc5205..152a9ee6 100644 --- a/src/Rdd.Domain/Helpers/Expressions/ExpressionParser.cs +++ b/src/Rdd.Domain/Helpers/Expressions/ExpressionParser.cs @@ -154,7 +154,14 @@ private PropertyInfo GetPropertyInfo(Type type, string name) } else { - return type.GetProperty(name, BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + var property = type.GetProperty(name, BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + + //Ef needs the property coming from the declaring type + if (property != null && property.ReflectedType != property.DeclaringType) + { + property = property.DeclaringType.GetProperty(name, BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + } + return property; } } } diff --git a/test/Rdd.Domain.Tests/Models/Hierarchy.cs b/test/Rdd.Domain.Tests/Models/Hierarchy.cs index 315879bd..57109e1a 100644 --- a/test/Rdd.Domain.Tests/Models/Hierarchy.cs +++ b/test/Rdd.Domain.Tests/Models/Hierarchy.cs @@ -13,6 +13,8 @@ public abstract class Hierarchy : IEntityBase public string Type { get; } + public long Value { get; set; } + public int Id { get; set; } public Hierarchy Clone() => this; @@ -25,6 +27,7 @@ public abstract class Hierarchy : IEntityBase public class Super : Hierarchy { public string SuperProperty { get; set; } + public long Value2 { get; set; } } public class SuperSuper : Super diff --git a/test/Rdd.Infra.Tests/HierarchyTests.cs b/test/Rdd.Infra.Tests/HierarchyTests.cs new file mode 100644 index 00000000..ef93e479 --- /dev/null +++ b/test/Rdd.Infra.Tests/HierarchyTests.cs @@ -0,0 +1,97 @@ +using Rdd.Domain.Helpers.Expressions; +using Rdd.Domain.Models.Querying; +using Rdd.Domain.Tests.Models; +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Xunit; + +namespace Rdd.Infra.Tests +{ + public class GenericKey + { + public long Sum { get; set; } + public string BaseProperty { get; set; } + } + + public class TypeOneKey : GenericKey + { + public string SuperProperty { get; set; } + } + + public class Metric + where TKey : GenericKey + { + public long Sum { get; set; } + public TKey Key { get; set; } + } + + public class TypeOneMetric : Metric + { + public long TypeOneProperty { get; set; } + } + + public class HierarchyTests : DatabaseTest + { + [Fact] + public async Task OrderByTest() + { + await RunCodeInsideIsolatedDatabaseAsync((context) => + { + using (var newContext = GetContext()) + { + newContext.Set().Add(new Super + { + BaseProperty = "a", + Value = 1 + }); + newContext.Set().Add(new Super + { + BaseProperty = "a", + Value = 2 + }); + newContext.Set().Add(new Super + { + BaseProperty = "b", + Value = 2 + }); + newContext.SaveChanges(); + + var query = newContext.Set().GroupBy(e => new + { + e.BaseProperty, + e.SuperProperty + }) + .Select(g => new TypeOneMetric + { + Sum = g.Sum(e => e.Value), + Key = new TypeOneKey + { + Sum = g.Sum(e => e.Value2), + BaseProperty = g.Key.BaseProperty, + SuperProperty = g.Key.SuperProperty + } + }); + + var set = new Service().ApplyOrderBys(query); + + var response = set.ToList(); + } + + return Task.CompletedTask; + }); + } + } + + public class Service where TMetric : Metric + where TKey : GenericKey + { + public IQueryable ApplyOrderBys(IQueryable entities) + { + var expression = new ExpressionParser().Parse("Sum"); + var orderBy = new OrderBy(expression.ToLambdaExpression()); + return orderBy.ApplyOrderBy(entities); + } + } +} \ No newline at end of file