System.Linq.Dynamic.Core icon indicating copy to clipboard operation
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.

Open mata007 opened this issue 4 years ago • 0 comments

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);

mata007 avatar May 02 '21 10:05 mata007