System.Linq.Dynamic.Core
System.Linq.Dynamic.Core copied to clipboard
The MethodFinder.FindMethod method ignores the name of the searched method when searching in methods returned by GetExtensionMethods.
In the example below, the method has no problem using the Test method even if I want to call DateDiffYear in the expression.
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
namespace LinqParserConsole
{
class Program
{
static void Main(string[] args)
{
Expression<Func<Person, bool>> exp = (p) => EF.Functions.DateDiffYear(p.DateOfBirth, DateTime.Now) < 18;
var exStr = exp.Body.ToString().Replace("p.", "$.");
var parsedExp = DynamicExpressionParser.ParseLambda<Person, bool>(new ParsingConfig() { CustomTypeProvider = new EFDynamicLinqCustomTypeProvider() }, true, exStr, null);
Console.WriteLine(parsedExp);
}
}
public class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class EFDynamicLinqCustomTypeProvider : System.Linq.Dynamic.Core.CustomTypeProviders.DefaultDynamicLinqCustomTypeProvider
{
public override HashSet<Type> GetCustomTypes()
{
var types = base.GetCustomTypes();
//types.Add(typeof(SqlServerDbFunctionsExtensions));
types.Add(typeof(TestDbFunctionsExtensions));
types.Add(typeof(DbFunctionsExtensions));
types.Add(typeof(EF));
return types;
}
}
public static class TestDbFunctionsExtensions
{
public static int Test(this DbFunctions _, DateTime startDate, DateTime endDate) => EF.Functions.DateDiffYear(startDate, endDate);
}
}
In my example, if I use the SqlServerDbFunctionsExtensions method in the GetCustomTypes method instead of TestDbFunctionsExtensions, an exception is returned that the searched method cannot be uniquely identified. Since it evaluates all methods from the DateDiff group as satisfying.
Maybe it would be enough to replace
int count = FindBestMethod(methods.Cast<MethodBase>(), ref extensionMethodArgs, out method);
with
int count = FindBestMethod(methods.Cast<MethodBase>().Where((m)=>StringComparer.OrdinalIgnoreCase.Equals(m.Name, methodName)), ref extensionMethodArgs, out method);