From 52e2deeeeea294c8fa14f0f482d8191240fcd473 Mon Sep 17 00:00:00 2001 From: Nathan Parkinson Date: Thu, 3 Jan 2019 15:25:43 +0000 Subject: [PATCH] allow for nested properties to add filter --- .../Accessors/IRootAccessor.cs | 1 + .../Accessors/RootAccessor.cs | 17 ++++++++ .../Visitors/PropertyVisitor.cs | 43 ++++++++++--------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/LinqToDB.Include/Accessors/IRootAccessor.cs b/src/LinqToDB.Include/Accessors/IRootAccessor.cs index 4dc5236..2948ef1 100644 --- a/src/LinqToDB.Include/Accessors/IRootAccessor.cs +++ b/src/LinqToDB.Include/Accessors/IRootAccessor.cs @@ -7,6 +7,7 @@ namespace LinqToDB.Include interface IRootAccessor { PropertyAccessor GetByPath(List pathParts) where TEntity : class where TProperty : class; + IPropertyAccessor GetByPath(List pathParts); MappingSchema MappingSchema { get; } } } \ No newline at end of file diff --git a/src/LinqToDB.Include/Accessors/RootAccessor.cs b/src/LinqToDB.Include/Accessors/RootAccessor.cs index 248cea9..a6c0f3b 100644 --- a/src/LinqToDB.Include/Accessors/RootAccessor.cs +++ b/src/LinqToDB.Include/Accessors/RootAccessor.cs @@ -30,6 +30,23 @@ PropertyAccessor IRootAccessor.GetByPath return result as PropertyAccessor; } + IPropertyAccessor IRootAccessor.GetByPath(List pathParts) + { + var thisPath = pathParts.First(); + + //TODO get by Type and PropertyName to account for multiple inherited classes with same PropertyName + var accessor = Properties.SingleOrDefault(x => x.PropertyName == thisPath); + if (accessor == null) + { + return null; + } + + var result = accessor.FindAccessor(pathParts.Skip(1).ToList()); + + return result; + } + + public void LoadMap(List entities, IQueryable query) { foreach (var propertyAccessor in Properties.OrderBy(x => x.PropertyName)) diff --git a/src/LinqToDB.Include/Visitors/PropertyVisitor.cs b/src/LinqToDB.Include/Visitors/PropertyVisitor.cs index 816f921..a9c52c4 100644 --- a/src/LinqToDB.Include/Visitors/PropertyVisitor.cs +++ b/src/LinqToDB.Include/Visitors/PropertyVisitor.cs @@ -15,14 +15,17 @@ internal PropertyVisitor(IRootAccessor rootAccessor) { _rootAccessor = rootAccessor; } - - - private static void AddFilterForInheritedType(IPropertyAccessor accessor, - Expression> includeFilter) - where T : class - where TProperty : class + + private static void AddFilterForDynamicType(IPropertyAccessor accessor, + Expression> includeFilter) + where T : class + where TProperty : class { - var accessorImpl = (PropertyAccessor)accessor; + var accessorImpl = accessor as PropertyAccessor; + if (accessorImpl == null) + { + throw new PropertyAccessorNotFoundException($"PropertyAccessor<{typeof(T).Name}, {typeof(TProperty).Name}> not found"); + } accessorImpl.AddFilter(includeFilter); } @@ -31,28 +34,27 @@ public IRootAccessor MapProperties(Expression; + //dupes at this point + if (!_rootAccessor.Properties.Contains(accessor)) + { + _rootAccessor.Properties.Add(accessor); + } + if (includeFilter != null) { if (latestAccessor is PropertyAccessor accessorImpl) { accessorImpl.AddFilter(includeFilter); } - else if (typeof(TClass).IsAssignableFrom(latestAccessor.DeclaringType)) - { - dynamic dynamicAccessor = latestAccessor; - AddFilterForInheritedType(dynamicAccessor, includeFilter); - } else { - throw new PropertyAccessorNotFoundException($"PropertyAccessor<{typeof(TClass).Name}, {typeof(TProperty).Name}> not found"); - } - } - - //dupes at this point - if (!_rootAccessor.Properties.Contains(accessor)) - { - _rootAccessor.Properties.Add(accessor); + //can type checking be added here? + var propertyAccessor = _rootAccessor.GetByPath(PathWalker.GetPath(expr)); + dynamic dynamicAccessor = propertyAccessor; + AddFilterForDynamicType(dynamicAccessor, includeFilter); + } } return _rootAccessor; @@ -86,6 +88,7 @@ protected override Expression VisitMember(MemberExpression node) { //check PropertyAccessor for the property does not already exist var localAccessor = CreateAccessor(node); + latestAccessor = localAccessor; return base.VisitMember(node); }