Skip to content

Commit

Permalink
Fixing issues #149 and #152 - errors using custom namespace. (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlaiseD authored Sep 26, 2022
1 parent 8b5d489 commit 153a230
Show file tree
Hide file tree
Showing 18 changed files with 1,127 additions and 435 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.ExpressionMapping" Version="[5.0.3,6.0.0)" />
<PackageReference Include="AutoMapper.Extensions.ExpressionMapping" Version="[5.1.0,6.0.0)" />
<PackageReference Include="EntityFramework" Version="6.3.0" />
<PackageReference Include="LogicBuilder.Expressions.Utils" Version="[5.0.6,6.0.0)" />
<PackageReference Include="Microsoft.AspNetCore.OData" Version="8.0.6" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.ExpressionMapping" Version="[5.0.3,6.0.0)" />
<PackageReference Include="AutoMapper.Extensions.ExpressionMapping" Version="[5.1.0,6.0.0)" />
<PackageReference Include="LogicBuilder.Expressions.Utils" Version="[5.0.6,6.0.0)" />
<PackageReference Include="Microsoft.AspNetCore.OData" Version="8.0.6" />
<PackageReference Include="MinVer" Version="2.5.0">
Expand Down
11 changes: 7 additions & 4 deletions AutoMapper.AspNetCore.OData.EFCore/FilterHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using LogicBuilder.Expressions.Utils.ExpressionBuilder.Logical;
using LogicBuilder.Expressions.Utils.ExpressionBuilder.Operand;
using LogicBuilder.Expressions.Utils.ExpressionBuilder.StringOperators;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.OData;
using Microsoft.OData.Edm;
using Microsoft.OData.UriParser;
Expand All @@ -22,15 +23,15 @@ namespace AutoMapper.AspNet.OData
{
public class FilterHelper
{
public FilterHelper(IDictionary<string, ParameterExpression> parameters, Type underlyingElementType)
public FilterHelper(IDictionary<string, ParameterExpression> parameters, Type underlyingElementType, ODataQueryContext context)
{
this.parameters = parameters;
parameterTypes.Push(underlyingElementType);
this.edmModel = context.Model;
}

private readonly IDictionary<string, ParameterExpression> parameters;
private static readonly IDictionary<EdmTypeStructure, Type> typesCache = TypeExtensions.GetEdmToClrTypeMappings();
private readonly Stack<Type> parameterTypes = new Stack<Type>();
private readonly IEdmModel edmModel;

public IExpressionPart GetFilterPart(QueryNode queryNode)
=> queryNode switch
Expand Down Expand Up @@ -497,7 +498,9 @@ private static object GetEnumValue(ODataEnumValue oDataEnum, Type enumType)
=> !(oDataEnum.Value ?? "").TryParseEnum(enumType, out object result) ? null : result;

private Type GetClrType(IEdmTypeReference typeReference)
=> TypeExtensions.GetClrType(typeReference, typesCache);
=> this.edmModel == null
? TypeExtensions.GetClrType(typeReference, typesCache)
: TypeExtensions.GetClrType(typeReference, edmModel, typesCache);

private IExpressionPart GetSingleValuePropertyAccessFilterPart(SingleValuePropertyAccessNode singleValuePropertyAccesNode)
{
Expand Down
34 changes: 24 additions & 10 deletions AutoMapper.AspNetCore.OData.EFCore/LinqExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public static Expression GetQueryableMethod(this Expression expression,
}

return expression
.GetOrderByCall(orderByClause)
.GetOrderByCall(orderByClause, context)
.GetSkipCall(skip)
.GetTakeCall(top);
}
Expand Down Expand Up @@ -204,14 +204,14 @@ Expression GetMethodCall() =>
expression.GetOrderByCall(settings.Name, nameof(Queryable.OrderBy));
}

private static Expression GetOrderByCall(this Expression expression, OrderByClause orderByClause)
private static Expression GetOrderByCall(this Expression expression, OrderByClause orderByClause, ODataQueryContext context)
{
const string OrderBy = "OrderBy";
const string OrderByDescending = "OrderByDescending";

return orderByClause.ThenBy == null
? GetMethodCall()
: GetMethodCall().GetThenByCall(orderByClause.ThenBy);
: GetMethodCall().GetThenByCall(orderByClause.ThenBy, context);

Expression GetMethodCall()
{
Expand All @@ -225,6 +225,7 @@ Expression GetMethodCall()
orderByClause.Direction == OrderByDirection.Ascending
? OrderBy
: OrderByDescending,
context,
orderByClause.RangeVariable.Name
);
default:
Expand All @@ -241,14 +242,14 @@ Expression GetMethodCall()
}
}

private static Expression GetThenByCall(this Expression expression, OrderByClause orderByClause)
private static Expression GetThenByCall(this Expression expression, OrderByClause orderByClause, ODataQueryContext context)
{
const string ThenBy = "ThenBy";
const string ThenByDescending = "ThenByDescending";

return orderByClause.ThenBy == null
? GetMethodCall()
: GetMethodCall().GetThenByCall(orderByClause.ThenBy);
: GetMethodCall().GetThenByCall(orderByClause.ThenBy, context);

Expression GetMethodCall()
{
Expand All @@ -259,7 +260,8 @@ Expression GetMethodCall()
countNode,
orderByClause.Direction == OrderByDirection.Ascending
? ThenBy
: ThenByDescending
: ThenByDescending,
context
),
SingleValuePropertyAccessNode propertyNode => expression.GetOrderByCall
(
Expand Down Expand Up @@ -381,7 +383,13 @@ public static LambdaExpression MakeLambdaExpression(this ParameterExpression par
return Expression.Lambda(delegateType, body, param);//Resulting lambda expression for the selector.
}

[Obsolete("\"Expression GetOrderByCountCall(this Expression expression, CountNode countNode, string methodName, ODataQueryContext context, string selectorParameterName = \"a\")\"")]
public static Expression GetOrderByCountCall(this Expression expression, CountNode countNode, string methodName, string selectorParameterName = "a")
{
return expression.GetOrderByCountCall(countNode, methodName, null, selectorParameterName);
}

public static Expression GetOrderByCountCall(this Expression expression, CountNode countNode, string methodName, ODataQueryContext context, string selectorParameterName = "a")
{
Type sourceType = expression.GetUnderlyingElementType();
ParameterExpression param = Expression.Parameter(sourceType, selectorParameterName);
Expand All @@ -392,7 +400,7 @@ public static Expression GetOrderByCountCall(this Expression expression, CountNo
{
string memberFullName = countNode.GetPropertyPath();
Type filterType = sourceType.GetMemberInfoFromFullName(memberFullName).GetMemberType().GetUnderlyingElementType();
LambdaExpression filterExpression = countNode.FilterClause.GetFilterExpression(filterType);
LambdaExpression filterExpression = countNode.FilterClause.GetFilterExpression(filterType, context);
countSelector = param.MakeSelector(memberFullName).GetCountCall(filterExpression);
}
else
Expand Down Expand Up @@ -563,14 +571,19 @@ bool HasQuery()
});
}

public static LambdaExpression GetFilterExpression(this FilterClause filterClause, Type type)
[Obsolete("\"LambdaExpression GetFilterExpression(this FilterClause filterClause, Type type, ODataQueryContext context)\"")]
public static LambdaExpression GetFilterExpression(this FilterClause filterClause, Type type)
=> filterClause.GetFilterExpression(type, null);

public static LambdaExpression GetFilterExpression(this FilterClause filterClause, Type type, ODataQueryContext context)
{
var parameters = new Dictionary<string, ParameterExpression>();

return new FilterHelper
(
parameters,
type
type,
context
)
.GetFilterPart(filterClause.Expression)
.GetFilter(type, parameters, filterClause.RangeVariable.Name);
Expand Down Expand Up @@ -629,7 +642,8 @@ Expression UpdateProjectionFilterExpression(Expression projectionExpression)
filterList => projectionExpression = ChildCollectionFilterUpdater.UpdaterExpansion
(
projectionExpression,
filterList
filterList,
context
)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.OData.Query;
using Microsoft.OData.Edm;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AutoMapper.AspNet.OData
Expand All @@ -11,11 +12,19 @@ public static OrderBySetting FindSortableProperties(this ODataQueryContext conte
{
context = context ?? throw new ArgumentNullException(nameof(context));

var entity = context.Model.FindDeclaredType(type.FullName) as IEdmEntityType;
var entity = GetEntity();
return entity is not null
? FindProperties(entity)
: throw new InvalidOperationException($"The type '{type.FullName}' has not been declared in the entity data model.");

IEdmEntityType GetEntity()
{
List<IEdmEntityType> entities = context.Model.SchemaElements.OfType<IEdmEntityType>().Where(e => e.Name == type.Name).ToList();
if (entities.Count == 1)
return entities[0];

return null;
}

static OrderBySetting FindProperties(IEdmEntityType entity)
{
Expand Down
39 changes: 37 additions & 2 deletions AutoMapper.AspNetCore.OData.EFCore/TypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using LogicBuilder.Expressions.Utils;
using Microsoft.AspNetCore.OData.Edm;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
Expand Down Expand Up @@ -67,13 +69,31 @@ private static Type GetClrType(EdmTypeStructure edmTypeStructure, IDictionary<Ed
throw new ArgumentException($"Cannot find CLT type for EDM type {edmTypeStructure.FullName}");
}

public static Type GetClrType(IEdmTypeReference edmTypeReference, IEdmModel edmModel, IDictionary<EdmTypeStructure, Type> typesCache)
{
if (edmTypeReference == null)
return typeof(object);

return edmModel.GetTypeMapper().GetClrType(edmModel, edmTypeReference, _AssemblyResolver);
}

private static IAssemblyResolver _assemblyResolver;
private static IAssemblyResolver _AssemblyResolver
{
get
{
_assemblyResolver ??= new AssemblyResolver();

return _assemblyResolver;
}
}

private static IList<Type> _loadedTypes = null;
public static IList<Type> LoadedTypes
{
get
{
if (_loadedTypes == null)
_loadedTypes = GetAllTypes(AppDomain.CurrentDomain.GetAssemblies().Distinct().ToList());
_loadedTypes ??= GetAllTypes(AppDomain.CurrentDomain.GetAssemblies().Distinct().ToList());

return _loadedTypes;
}
Expand Down Expand Up @@ -106,5 +126,20 @@ List<Type> DoLoad(List<Type> allTypes)

public static Dictionary<EdmTypeStructure, Type> GetEdmToClrTypeMappings() => Constants.EdmToClrTypeMappings;

private class AssemblyResolver : IAssemblyResolver
{
private List<Assembly> _assemblides;
public IEnumerable<Assembly> Assemblies
{
get
{
if (_assemblides == null)
_assemblides = AppDomain.CurrentDomain.GetAssemblies().Distinct().ToList();

return _assemblides;
}
}
}

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Microsoft.AspNetCore.OData.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
Expand All @@ -7,25 +8,29 @@ namespace AutoMapper.AspNet.OData.Visitors
{
internal class ChildCollectionFilterUpdater : ProjectionVisitor
{
public ChildCollectionFilterUpdater(List<ODataExpansionOptions> expansions) : base(expansions)
public ChildCollectionFilterUpdater(List<ODataExpansionOptions> expansions, ODataQueryContext context) : base(expansions)
{
this.context = context;
}

public static Expression UpdaterExpansion(Expression expression, List<ODataExpansionOptions> expansions)
=> new ChildCollectionFilterUpdater(expansions).Visit(expression);
private readonly ODataQueryContext context;

public static Expression UpdaterExpansion(Expression expression, List<ODataExpansionOptions> expansions, ODataQueryContext context)
=> new ChildCollectionFilterUpdater(expansions, context).Visit(expression);

protected override Expression GetBindingExpression(MemberAssignment binding, ODataExpansionOptions expansion)
{
if (expansion.FilterOptions != null)
{
return FilterAppender.AppendFilter(binding.Expression, expansion);
return FilterAppender.AppendFilter(binding.Expression, expansion, context);
}
else if (expansions.Count > 1) //Mutually exclusive with expansion.Filter != null.
{ //There can be only one filter in the list. See the GetFilters() method in QueryableExtensions.UpdateQueryable.
return UpdaterExpansion
(
binding.Expression,
expansions.Skip(1).ToList()
expansions.Skip(1).ToList(),
context
);
}
else
Expand Down
11 changes: 7 additions & 4 deletions AutoMapper.AspNetCore.OData.EFCore/Visitors/FilterAppender.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
using LogicBuilder.Expressions.Utils;
using Microsoft.AspNetCore.OData.Query;
using System;
using System.Linq.Expressions;

namespace AutoMapper.AspNet.OData.Visitors
{
internal class FilterAppender : ExpressionVisitor
{
public FilterAppender(Expression expression, ODataExpansionOptions expansion)
public FilterAppender(Expression expression, ODataExpansionOptions expansion, ODataQueryContext context)
{
this.expansion = expansion;
this.expression = expression;
this.context = context;
}

private readonly ODataExpansionOptions expansion;
private readonly Expression expression;
private readonly ODataQueryContext context;

public static Expression AppendFilter(Expression expression, ODataExpansionOptions expansion)
=> new FilterAppender(expression, expansion).Visit(expression);
public static Expression AppendFilter(Expression expression, ODataExpansionOptions expansion, ODataQueryContext context)
=> new FilterAppender(expression, expansion, context).Visit(expression);

protected override Expression VisitMethodCall(MethodCallExpression node)
{
Expand All @@ -31,7 +34,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
"Where",
new Type[] { node.GetUnderlyingElementType() },
node,
expansion.FilterOptions.FilterClause.GetFilterExpression(elementType)
expansion.FilterOptions.FilterClause.GetFilterExpression(elementType, context)
);
}

Expand Down
Loading

0 comments on commit 153a230

Please sign in to comment.