简体   繁体   English

C# Linq 从结果中删除字符以进行比较

[英]C# Linq Remove characters from results for comparison

I have a linq query which fetches records from SQL server database.我有一个 linq 查询,它从 SQL 服务器数据库中获取记录。 Phone numbers for example are stored as strings and can contain spaces or characters that when searching are not found.例如,电话号码存储为字符串,并且可以包含搜索时找不到的空格或字符。

ie I search for a phone number "0123456789" but in the database it's stored as "01234 567890" or "01234-567890" etc. In my code below you can see my attempts to strip out the characters (right or wrongly!) but I still do not get any results unless I search for the characters after the empty space "567890".即我搜索电话号码“0123456789”,但在数据库中它存储为“01234 567890”或“01234-567890”等。在我下面的代码中,您可以看到我尝试删除字符(正确或错误!)但是除非我搜索空格“567890”之后的字符,否则我仍然没有得到任何结果。

With the code below:使用以下代码:

"567890" returns correct results “567890”返回正确结果

"01202 567890" returns no results “01202 567890”不返回任何结果

"01202567890" returns no results “01202567890”不返回任何结果

    Expression<Func<Customer, bool>> SearchVals = ContainsInDescription("01234567890");

    var query = (from customer in data.Customers.Where(SearchVals)
                                 where customer.Deleted == false
                                 orderby customer.Name ascending
                                 select new
                                 {
                                     CustomerID = customer.CustomerID.ToString(),
                                     Name = customer.Name,
                                     Company = customer.Company,
                                     Home = customer.PhoneHome.Replace(" ", ""),
                                     Mobile = customer.PhoneMobile.Replace(" ", ""),
                                     Work = customer.PhoneWork.Replace(" ", ""),
                                     Email = customer.Email,
                                     Address1 = customer.Address.AddressLine1,
                                     Address2 = customer.Address.AddressLine2,
                                     City = customer.Address.City,
                                     County = customer.Address.County,
                                     Postcode = customer.Address.PostalCode,
                                     Country = customer.Address.Country
                                 }).Skip(totalToDisplay * page).Take(totalToDisplay);

public Expression<Func<Customer, bool>> ContainsInDescription(
                                                        params string[] keywords)
        {
            Expression<Func<Customer, bool>> predicate = PredicateBuilder.False<Customer>();
            foreach (string keyword in keywords)
            {
                string temp = keyword;

                //string predicate1 = PhoneHome.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim();
                string predicate2 = temp.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim();

                predicate = predicate.Or(p => p.Name.Contains(temp));
                predicate = predicate.Or(p => p.Company.Contains(temp));

                predicate = predicate.Or(p => p.PhoneHome.Contains(temp));
                predicate = predicate.Or(p => p.PhoneMobile.Contains(temp));
                predicate = predicate.Or(p => p.PhoneWork.Contains(temp));
                //predicate = predicate.Or(p => p.PhoneHome.ToString().Replace(" ", "").Replace("-", "").Contains(temp.ToString().Replace(" ", "").Replace("-", "")));
                //predicate = predicate.Or(p => p.PhoneMobile.ToString().Replace(" ", "").Replace("-", "").Contains(temp.ToString().Replace(" ", "").Replace("-", "")));
                //predicate = predicate.Or(p => p.PhoneWork.ToString().Replace(" ", "").Replace("-", "").Contains(temp.ToString().Replace(" ", "").Replace("-", "")));
                //predicate = predicate.Or(p => p.PhoneHome.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim() == temp.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim());
                //predicate = predicate.Or(p => p.PhoneMobile.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim() == temp.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim());
                //predicate = predicate.Or(p => p.PhoneWork.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim() == temp.ToString().Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "").Trim());

                predicate = predicate.Or(p => p.Email.Contains(temp));
                predicate = predicate.Or(p => p.Address.AddressLine1.Contains(temp));
                predicate = predicate.Or(p => p.Address.AddressLine2.Contains(temp));
                predicate = predicate.Or(p => p.Address.City.Contains(temp));
                predicate = predicate.Or(p => p.Address.County.Contains(temp));
                predicate = predicate.Or(p => p.Address.PostalCode.Contains(temp));
                predicate = predicate.Or(p => p.Address.Country.Contains(temp));
            }
            return predicate;
        }

You might need to clean the data you gather from the database as well.您可能还需要清理从数据库收集的数据。 Currently you only remove spaces.目前您只删除空格。 Instead of replacing lots of stuff, consider using a whitelist approach:与其替换大量内容,不如考虑使用白名单方法:

using System;
using System.Linq;
using System.Text;

public static void Main()
{
    Func<string, String> onlyNumbers = data 
      => data.Where(c => char.IsDigit(c))  // only keep digits
             .Aggregate(new StringBuilder(),(builder, c) => builder.Append(c))
             .ToString(); // gimme concatted string
    
    Console.WriteLine(onlyNumbers( "sadf(234)-23492sas" ));  // =>   "23423492"
}

using above "cleaner" something like使用上面的“清洁器”之类的东西

...
Mobile = onlyNumbers(customer.PhoneMobile),
Home = onlyNumbers(customer.PhoneHome),
Mobile = onlyNumbers(customer.PhoneMobile),
Work = onlyNumbers(customer.PhoneWork),
...

and

pred = pred.Or(p => p.Mobile.Contains(onlyNumbers(_some_input_)));

should do the trick.应该做的伎俩。

Instead of char.IsDigit() you could define your own hashset of allowed characters (or allow '+' as well) to allow fe international pre-dial numbers given as +41 1234 5678 90除了char.IsDigit()您还可以定义自己的允许字符散列集(或也允许 '+')以允许 fe 国际预拨号码为+41 1234 5678 90

Caveat - this will generate numebers from any text and might give you false-positives:警告 - 这将从任何文本生成数字,并可能给你误报:

onlyNumbers("This 246 cars had 102 violations of rule 47.11 in the year 2012");

gives you a string of "24610247112012" .给你一串"24610247112012"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM