Skip to content

Commit

Permalink
ok!
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Sep 9, 2023
1 parent 478d32c commit 547f0ce
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 32 deletions.
11 changes: 8 additions & 3 deletions src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1802,10 +1802,15 @@ public static IQueryable<TResult> Select<TResult>(this IQueryable source, Parsin
bool createParameterCtor = config.EvaluateGroupByAtDatabase || SupportsLinqToObjects(config, source);
LambdaExpression lambda = DynamicExpressionParser.ParseLambda(config, createParameterCtor, source.ElementType, typeof(TResult), selector, args);

var optimized = OptimizeExpression(Expression.Call(
typeof(Queryable), nameof(Queryable.Select),
var e = Expression.Call(
typeof(Queryable),
nameof(Queryable.Select),
new[] { source.ElementType, typeof(TResult) },
source.Expression, Expression.Quote(lambda)));
source.Expression,
Expression.Quote(lambda)
);

var optimized = OptimizeExpression(e);



Expand Down
84 changes: 62 additions & 22 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1813,30 +1813,70 @@ private Expression ParseMemberAccess(Type? type, Expression? expression)
methodToCall = method.MakeGenericMethod(typeArguments.ToArray());
}

return Expression.Call(expression, methodToCall, args);
//return Expression.Call(expression, methodToCall, args);
// stef
//#if NET35
// return Expression.Call(expression, methodToCall, args);
//#else
// var outParameters = args.OfType<ParameterExpression>().Where(p => p.IsByRef).ToArray();
// if (outParameters.Any())
// {
// var variablesInScope = outParameters.Select(p => Expression.Variable(p.Type, p.Name)).ToArray();
#if NET35
return Expression.Call(expression, methodToCall, args);
#else
var outParameters = args.OfType<ParameterExpression>().Where(p => p.IsByRef).ToArray();
if (outParameters.Any())
{
//var a = new List<Expression>();
var outVars = new List<Expression>();
var inP = new List<Expression>();

foreach (var a in args)
{
if (a is ParameterExpression parameterExpression && parameterExpression.IsByRef)
{
var outputVar = Expression.Variable(parameterExpression.Type, parameterExpression.Name);
// a.Add(outputVar);
outVars.Add(outputVar);
}
else
{
// a.Add(parameterExpression);
inP.Add(a);
}
}

// Create a method call expression
//var methodCall = Expression.Call(expression, methodToCall, args);

// Create a variable expression to hold the 'out' parameter.
var outVar = Expression.Variable(typeof(string), "xxx");

// Create a method call expression to call User.TryParse.
var methodCall = Expression.Call(
expression,
methodToCall,
new Expression[] { args[0], outVar }
);


// Create a variable to hold the return value
var returnValue = Expression.Variable(methodToCall.ReturnType, "returnValue");

var userParam = (ParameterExpression) expression;//Expression.Parameter(expression!.Type, "user");

// var block = Expression.Block(
// variablesInScope, // Declare variables used inside the block
// Expression.Call(expression, methodToCall, args) // Expression body
// // Expression.Variable(methodToCall.ReturnType)
// //inScope[0]
// //variablesInScope[0]
// //
// );

// return Expression.Lambda(block);
// }

// return Expression.Call(expression, methodToCall, args);
//#endif
// Create the block to return the boolean value.
var block = Expression.Block(
new[] { outVar, returnValue },
Expression.Assign(returnValue, methodCall),
returnValue
);

// Create the lambda expression
var lambda = Expression.Lambda(
block,
userParam
);

return lambda;
}

return Expression.Call(expression, methodToCall, args);
#endif

default:
throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, TypeHelper.GetTypeName(type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public void ExpressionTests_MethodCall_Out()
var users = User.GenerateSampleModels(5);

// Act
string? un = null;
var expected = users.Select(u => u.TryGetUserName(out un));
var result = users.AsQueryable().Select<bool>(config, "TryGetUserName($out _)");
string un = "";
var expected = users.Select(u => u.TryParseWithArgument(u.UserName, out un));
var result = users.AsQueryable().Select<bool>(config, "TryParseWithArgument(it.UserName, $out _)");

// Assert
result.Should().BeEquivalentTo(expected);
Expand Down
8 changes: 4 additions & 4 deletions test/System.Linq.Dynamic.Core.Tests/Helpers/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ public bool TestMethod3(User other)
return Id == other.Id;
}

public bool TryGetUserName(out string? username)
public bool TryParseWithArgument(string s, out string xxx)
{
if (UserName.EndsWith("1") || UserName.EndsWith("2"))
if (s.EndsWith("1") || s.EndsWith("2"))
{
username = UserName;
xxx = UserName;
return true;
}

username = null;
xxx = "";
return false;
}

Expand Down

0 comments on commit 547f0ce

Please sign in to comment.