Details
-
Bug
-
Resolution: Fixed
-
Major - P3
-
2.10.4, 2.11.0-beta2
-
.net core 3.1
Description
I found case then LINQ filter fail with exception if one of expression member is null.
For example we have orders which bounded to factory (view FactoryId field):
class Order |
{
|
public int Id {get;set;} |
public int FactoryId {get;set;} |
|
}
|
|
We have current user, each user can be bound to factory or can be system wide (factory = null):
class User |
{
|
public int Id {get;set;} |
public Factory Factory {get;set;} |
}
|
|
|
class Factory |
{
|
public int Id {get;set;} |
}
|
Now i want to get all orders which current user can access to:
var orders = db
|
.GetCollection<Order>("order1").AsQueryable() |
.Where(x => currentUser.Factory == null || x.FactoryId == currentUser.Factory.Id); |
In case of system wide user (currentUser.Factory = null) i get exception of type System.Reflection.TargetException: Non-static method requires a target with following stacktrace:
System.Reflection.TargetException: Non-static method requires a target. |
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
|
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
|
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
|
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
|
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
|
at System.Reflection.PropertyInfo.GetValue(Object obj)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.ReflectionEvaluator.VisitMember(MemberExpression node)
|
at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
|
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.ReflectionEvaluator.Evaluate(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.EvaluateSubtree(Expression subtree)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
|
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
|
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
|
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
|
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node) |
at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor) |
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
|
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
|
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
|
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
|
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
|
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
|
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Evaluate(Expression node)
|
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Prepare(Expression expression) |
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Translate(Expression expression) |
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression) |
at MongoDB.Driver.Linq.MongoQueryableImpl`2.GetEnumerator() |
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items) |
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source) |
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) |
at ConsoleApp1.Program.Main(String[] args) in D:\ConsoleApp1\ConsoleApp1\Program.cs:line 56 |
If current user bounded to factory all work fine.
i try to rewrite to condition operator:
var orders = db
|
.GetCollection<Order>("order1").AsQueryable() |
.Where(x => currentUser.Factory == null ? true : x.FactoryId == currentUser.Factory.Id) |
But with no luck - IIF operator does not work.
I create fiddle with sample code that reproduce this behaviour: https://dotnetfiddle.net/iFIkrA