C# 将lambda表达式转换为表达式树

C# 将lambda表达式转换为表达式树,c#,.net,linq,expression-trees,C#,.net,Linq,Expression Trees,我试图解决的现实世界的问题是:我有一个数据库,其中有一堆电话号码以绝对糟糕的格式存储为字符串(例如“(02)9971 1209”)。我的程序的用户将开始键入一个电话号码,当他键入时,他正在键入的内容将被发送出去,并用于使用“startswith”操作过滤数据库中的电话号码列表 问题是,如果用户键入“02997”,它将不匹配任何内容,因为这些数字存储在括号中的位置代码中。为了使此操作正常工作,用户必须通过键入“(”)开始每次搜索。这不好 tl;问题底部的dr版本 我把问题从现实世界的背景中带出来,

我试图解决的现实世界的问题是:我有一个数据库,其中有一堆电话号码以绝对糟糕的格式存储为字符串(例如“(02)9971 1209”)。我的程序的用户将开始键入一个电话号码,当他键入时,他正在键入的内容将被发送出去,并用于使用“startswith”操作过滤数据库中的电话号码列表

问题是,如果用户键入“02997”,它将不匹配任何内容,因为这些数字存储在括号中的位置代码中。为了使此操作正常工作,用户必须通过键入“(”)开始每次搜索。这不好

tl;问题底部的dr版本

我把问题从现实世界的背景中带出来,放到了一个更小的、封闭的解决方案中,在这个解决方案中,我可以专注于它,而不受大规模代码库的干扰。在这种情况下,我的解决方案是做一些linq技巧:

class Program
{
    static string [] phones = {"(02) 9489 3048","(04) 1128 2148","(01) 9971 1208",};

    static void Main(string[] args)
    {
        for (;;)
        {
            Console.WriteLine("Enter your number: ");
            string input = Console.ReadLine();

            Func<string, string> strip = 
            tehstring => tehstring.Where(x => char.IsDigit(x))
                                  .Aggregate("", (x, y) => x + y);
            var results = phones.Where(z => strip(z).StartsWith(strip(input)));

            foreach (var x in results)
                Console.WriteLine(x);
        }
    }
}
我需要使用propertyExpression,并以某种方式将它所谈论的属性(在本例中是外部数据库中的电话号码表)嵌入到我的lambda函数中。然后我需要将整个内容反编译回表达式树并返回它

这就是我被卡住的地方。我能想到的最好的是超长且不雅观的linq系列,它甚至没有正确的类型:

Expression<Func<string[],string, IEnumerable<string>>> expr = 
(db, uinput) => db.Where(z => z.Where(x => char.IsDigit(x))
                               .Aggregate("", (x, y) => x + y)
                               .StartsWith(uinput.Where(x => char.IsDigit(x))
                                                 .Aggregate("",(x,y) => x + y)));
表达式表达式=
(db,uinput)=>db.Where(z=>z.Where(x=>char.IsDigit(x))
.Aggregate(“,(x,y)=>x+y)
.StartsWith(uinput.Where(x=>char.IsDigit(x))
.聚合(“,(x,y)=>x+y));
我想做一些类似的事情,这仍然不能解决问题,但稍微整洁一些:

Expression<Func<string, string>> strip = 
tehstring => tehstring.Where(x => char.IsDigit(x))
                      .Aggregate("", (x, y) => x + y);
Expression<Func<string, string, string>> query = 
(db, uinput) => db.Where(z => strip(z)
                  .StartsWith(strip(uinput)));
表达式条=
tehstring=>tehstring.Where(x=>char.IsDigit(x))
.骨料(“,(x,y)=>x+y);
表达式查询=
(db,uinput)=>db.其中(z=>strip(z)
.StartsWith(strip(uinput));
我尝试过对它进行很多小的修改,但它拒绝编译

tl;dr:


长话短说,我需要做的是获取一个表示数据库表中某个字段的表达式,并将该表达式转换为表示相同内容的表达式,但应用了一个过滤器,以去除所有非数字的字符。

许多您希望用于获取电话号码的去除版本的表达式您的LINQ提供商可能不支持


我个人建议创建一个数据库视图,以精简格式显示所有电话号码。然后,您可以对该视图执行标准的
StartsWith
查询。

您想要获取精简版电话号码的许多表达式可能不受LINQ提供商的支持


我个人建议创建一个数据库视图,以精简格式显示所有电话号码。然后,您可以对该视图执行标准的
StartsWith
查询。

对,尤其是no
char.IsDigit
。我担心可能会出现这种情况。我仍然希望尝试使用我的linq提供程序,如ch更改电话号码的格式是不行的。我会研究一下你的databaseview建议too@TheIronKnuckle:另一个选项是在数据库中创建一个用户定义的函数,并在linq查询中调用它。无论哪种方式,您都必须在数据库中创建一些内容,因为我想不出任何方法来执行您在g由LINQ to SQL或LINQ to Entities实现的方法。换句话说,即使您编译了它,它也会在运行时引发异常。对,尤其是no
char.IsDigit
。我担心可能会出现这种情况。无论如何,我还是想尝试使用我的LINQ提供程序,因为更改电话号码的格式是不可能的o、 我会研究你的databaseview建议too@TheIronKnuckle:另一种选择是在数据库中创建一个用户定义的函数,并在linq查询中调用它。无论是哪种方式,您都必须在数据库上创建一些内容,因为我想不出任何方法可以使用linq to SQL或linq实现的方法来实现您的要求换句话说,即使你编译了它,它也会在运行时抛出异常。
Expression<Func<string, string>> strip = 
tehstring => tehstring.Where(x => char.IsDigit(x))
                      .Aggregate("", (x, y) => x + y);
Expression<Func<string, string, string>> query = 
(db, uinput) => db.Where(z => strip(z)
                  .StartsWith(strip(uinput)));