public override void VisitMethodCall(MethodCallExpression node, QueryBuilder <TEntity> state) { MethodInfo method = node.Method.IsGenericMethod ? node.Method.GetGenericMethodDefinition() : node.Method; if (method == KnownMethods.EnumerableCount || method == KnownMethods.EnumerableLongCount) { state.SetAggregation(AggregationOperation.Count); } else if (method == KnownMethods.EnumerableMaxDirect) { state.SetAggregation(AggregationOperation.Max); } else if (method == KnownMethods.EnumerableMinDirect) { state.SetAggregation(AggregationOperation.Min); } else if (method == KnownMethods.EnumerableCountPredicate || method == KnownMethods.EnumerableLongCountPredicate) { var right = node.Arguments[1]; state.SetAggregation(AggregationOperation.Count); if (right is LambdaExpression lambda) { state.BeginWhereSection(); WhereVisitor <TEntity> .Instance.Visit(lambda.Body, state); state.EndWhereSection(); } } else if (KnownMethods.IsEnumerableMax(method)) { var right = node.Arguments[1]; state.SetAggregation(AggregationOperation.Max); Visit(right, state); } else if (KnownMethods.IsEnumerableMin(method)) { var right = node.Arguments[1]; state.SetAggregation(AggregationOperation.Min); Visit(right, state); } else if (KnownMethods.IsEnumerableSum(method)) { var right = node.Arguments[1]; state.SetAggregation(AggregationOperation.Sum); Visit(right, state); } else if (KnownMethods.IsEnumerableAverage(method)) { var right = node.Arguments[1]; state.SetAggregation(AggregationOperation.Average); Visit(right, state); } else { base.VisitMethodCall(node, state); } }
public bool KnowMethod(MethodSpec m) { if (!KnownMethods.Contains(m)) { KnownMethods.Add(m); return(true); } return(false); }
public void IsSerializationConstructor_Null_ShouldBeFalse() => KnownMethods.IsSerializationConstructor(null).Should().BeFalse();
public void IsGetObjectData_Null_ShouldBeFalse() => KnownMethods.IsGetObjectData(null).Should().BeFalse();
public void IsIEquatableEquals_Null_ShouldBeFalse() => KnownMethods.IsIEquatableEquals(null).Should().BeFalse();
public void IsOperatorBinaryModulus_Null_ShouldBeFalse() => KnownMethods.IsOperatorBinaryModulus(null).Should().BeFalse();
public void IsOperatorBinaryMultiply_Null_ShouldBeFalse() => KnownMethods.IsOperatorBinaryMultiply(null).Should().BeFalse();
public void IsDebugAssert_Null_ShouldBeFalse() => KnownMethods.IsDebugAssert(null).Should().BeFalse();
public void IsMainMethod_Null_ShouldBeFalse() => KnownMethods.IsMainMethod(null).Should().BeFalse();
public void IsEnumerableConcat_Null_ShouldBeFalse() => KnownMethods.IsEnumerableConcat(null).Should().BeFalse();
public void IsEventHandler_Null_ShouldBeFalse() => KnownMethods.IsEventHandler(null).Should().BeFalse();
public void IsListAddRange_Null_ShouldBeFalse() => KnownMethods.IsListAddRange(null).Should().BeFalse();
public void IsConsoleWrite_Null_ShouldBeFalse() => KnownMethods.IsConsoleWrite(null).Should().BeFalse();
public void IsOperatorNotEquals_Null_ShouldBeFalse() => KnownMethods.IsOperatorNotEquals(null).Should().BeFalse();
public void IsArrayClone_Null_ShouldBeFalse() => KnownMethods.IsArrayClone(null).Should().BeFalse();
public void IsGcSuppressFinalize_Null_ShouldBeFalse() => KnownMethods.IsGcSuppressFinalize(null).Should().BeFalse();
public void IsStaticObjectEquals_Null_ShouldBeFalse() => KnownMethods.IsStaticObjectEquals(null).Should().BeFalse();
public void IsDiagnosticDebugMethod_Null_ShouldBeFalse() => KnownMethods.IsDiagnosticDebugMethod(null).Should().BeFalse();
public void IsObjectGetHashCode_Null_ShouldBeFalse() => KnownMethods.IsObjectGetHashCode(null).Should().BeFalse();
public void IsOperatorBinaryDivide_Null_ShouldBeFalse() => KnownMethods.IsOperatorBinaryDivide(null).Should().BeFalse();
public void IsObjectToString_Null_ShouldBeFalse() => KnownMethods.IsObjectToString(null).Should().BeFalse();
public void IsIAsyncDisposableDisposeAsync_Null_ShouldBeFalse() => KnownMethods.IsIAsyncDisposableDisposeAsync(null).Should().BeFalse();
public override void VisitMethodCall(MethodCallExpression node, QueryBuilder <TEntity> state) { var method = node.Method.IsGenericMethod ? node.Method.GetGenericMethodDefinition() : node.Method; if (method == KnownMethods <TEntity> .QueryableDeletePred) { state.ResultMethod = QueryResultMethod.Delete; var expression = node.Arguments[0]; VisitWhere(expression, state); } else if (method == KnownMethods <TEntity> .QueryableDeleteAll) { state.ResultMethod = QueryResultMethod.Delete; } else if (method == KnownMethods <TEntity> .QueryableFirstOrDefaultPred || method == KnownMethods <TEntity> .QueryableAnyPred) { state.ResultMethod = method == KnownMethods <TEntity> .QueryableFirstOrDefaultPred ? QueryResultMethod.FirstOrDefault : QueryResultMethod.Any; var expression = node.Arguments[0]; VisitWhere(expression, state); } else if (method == KnownMethods <TEntity> .QueryableFirstOrDefault || method == KnownMethods <TEntity> .QueryableAny) { state.ResultMethod = method == KnownMethods <TEntity> .QueryableFirstOrDefault ? QueryResultMethod.FirstOrDefault : QueryResultMethod.Any; } else if (method == KnownMethods.QueryableFirstOrDefaultPred || method == KnownMethods.QueryableFirstPred || method == KnownMethods.QueryableSingleOrDefaultPred || method == KnownMethods.QueryableSinglePred || method == KnownMethods.QueryableAnyPred || method == KnownMethods.QueryableAllPred) { var left = node.Arguments[0]; Visit(left, state); state.ResultMethod = method == KnownMethods.QueryableFirstOrDefaultPred ? QueryResultMethod.FirstOrDefault : method == KnownMethods.QueryableFirstPred ? QueryResultMethod.First : method == KnownMethods.QueryableSingleOrDefaultPred ? QueryResultMethod.SingleOrDefault : method == KnownMethods.QueryableSinglePred ? QueryResultMethod.Single : method == KnownMethods.QueryableAnyPred ? QueryResultMethod.Any : QueryResultMethod.All; var expression = node.Arguments[1]; if (state.ResultMethod == QueryResultMethod.All) { state.AllMethodExpression = expression; } else { VisitWhere(expression, state); } } else if (method == KnownMethods.QueryableFirstOrDefault || method == KnownMethods.QueryableFirst || method == KnownMethods.QueryableSingleOrDefault || method == KnownMethods.QueryableSingle || method == KnownMethods.QueryableAny) { var left = node.Arguments[0]; Visit(left, state); state.ResultMethod = method == KnownMethods.QueryableFirstOrDefault ? QueryResultMethod.FirstOrDefault : method == KnownMethods.QueryableFirst ? QueryResultMethod.First : method == KnownMethods.QueryableSingleOrDefault ? QueryResultMethod.SingleOrDefault : method == KnownMethods.QueryableSingle ? QueryResultMethod.Single : QueryResultMethod.Any; } else if (method == KnownMethods.QueryableWhere) { var left = node.Arguments[0]; Visit(left, state); var expression = node.Arguments[1]; VisitWhere(expression, state); } else if (method == KnownMethods.QueryableCountPredicate || method == KnownMethods.QueryableLongCountPredicate) { var left = node.Arguments[0]; Visit(left, state); var expression = node.Arguments[1]; VisitWhere(expression, state); state.SetAggregation(AggregationOperation.Count); } else if (method == KnownMethods.QueryableTake) { if (node.Arguments[1] is ConstantExpression takeConstExpression) { var value = (int)takeConstExpression.Value; state.Fetch(value); Visit(node.Arguments[0], state); } else if (node.Arguments[1] is MemberExpression takeMemberExpression) { var value = (int)takeMemberExpression.RetrieveMemberValue(); state.Fetch(value); Visit(node.Arguments[0], state); } else { throw new NotSupportedException(); } } else if (method == KnownMethods.QueryableSkip) { if (node.Arguments[1] is ConstantExpression skipConstExpression) { var value = (int)skipConstExpression.Value; state.Offset(value); Visit(node.Arguments[0], state); } else if (node.Arguments[1] is MemberExpression takeMemberExpression) { var value = (int)takeMemberExpression.RetrieveMemberValue(); state.Offset(value); Visit(node.Arguments[0], state); } else { throw new NotSupportedException(); } } else if (method.IsGenericMethod) { var gen = method.GetGenericMethodDefinition(); //Why cannot this be done like the above? //Because OrderBy use Func<T,TKeySelector> where TKeySelector is unknown to us here //That is, it is the return type of the property if (gen == KnownMethods.QueryableOrderBy) { VisitOrderBy(node, state, true); } else if (gen == KnownMethods.QueryableOrderByDesc) { VisitOrderBy(node, state, false); } else if (gen == KnownMethods.QueryableThenBy) { VisitOrderBy(node, state, true); } else if (gen == KnownMethods.QueryableThenByDesc) { VisitOrderBy(node, state, false); } else if (gen == KnownMethods.QueryableSelect) { var left = node.Arguments[0]; var right = node.Arguments[1]; Visit(left, state); SelectVisitor <TEntity> .Instance.Visit(right, state); } else if (gen == KnownMethods.QueryableWhere) { var left = node.Arguments[0]; var expression = node.Arguments[1]; Visit(left, state); VisitWhere(expression, state); } else if (gen == KnownMethods.QueryableGroupBy) { VisitGroupBy(node, state); } else if (gen == KnownMethods.QueryableCount || gen == KnownMethods.QueryableLongCount) { var left = node.Arguments[0]; Visit(left, state); state.SetAggregation(AggregationOperation.Count); } else if (KnownMethods.IsQueryableAverage(gen)) { var left = node.Arguments[0]; var right = node.Arguments[1]; Visit(left, state); state.SetAggregation(AggregationOperation.Average); SelectVisitor <TEntity> .Instance.Visit(right, state); } else if (gen == KnownMethods.QueryableMin) { var left = node.Arguments[0]; var right = node.Arguments[1]; Visit(left, state); state.SetAggregation(AggregationOperation.Min); SelectVisitor <TEntity> .Instance.Visit(right, state); } else if (gen == KnownMethods.QueryableMax) { var left = node.Arguments[0]; var right = node.Arguments[1]; Visit(left, state); state.SetAggregation(AggregationOperation.Max); SelectVisitor <TEntity> .Instance.Visit(right, state); } else if (KnownMethods.IsQueryableSum(gen)) { var left = node.Arguments[0]; var right = node.Arguments[1]; Visit(left, state); state.SetAggregation(AggregationOperation.Sum); SelectVisitor <TEntity> .Instance.Visit(right, state); } } }