0

I have to search for a key (product) from ucommerce products.

Here is the code -

string whatToSearch = "L'oreal";

var normalizedText = whatToSearch.Normalize(NormalizationForm.FormD);

whatToSearch = nonSpacingMarkRegex.Replace(normalizedText, string.Empty);

whatToSearch = Regex.Replace(whatToSearch, @"[^0-9a-zA-Z ]+", "");

var products = new List<UCommerce.EntitiesV2.Product>();

if (!string.IsNullOrWhiteSpace(whatToSearch))
{
    products = UCommerce.EntitiesV2.Product.Find(p =>
            p.VariantSku == null && p.DisplayOnSite &&
            (
                p.Sku.Contains(whatToSearch)
                || p.Name.RemoveDiacritics().Contains(whatToSearch)
                || p.ProductDescriptions.Any(
                    d => d.DisplayName.Contains(whatToSearch)
                         || d.ShortDescription.Contains(whatToSearch)
                         || d.LongDescription.Contains(whatToSearch)
                )
            )
    );
}

 var productIds = products.Select(x => x.Id).ToList();

And this is the extension method I am using inside the loop.

public static string RemoveDiacritics(this string s)
{
    var normalizedString = s.Normalize(NormalizationForm.FormD);
    var stringBuilder = new StringBuilder();

    foreach (var c in normalizedString)
    {
        if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
            stringBuilder.Append(c);
    }

    return stringBuilder.ToString();
}

I am getting this exception System.String RemoveDiacritics(System.String)

Can anyone help.

Thanks

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
Harsheet
  • 728
  • 9
  • 23
  • There must be something else besides the name of the function! – TheVillageIdiot Mar 14 '17 at 01:18
  • The `Regex.Replace(whatToSearch, @"[^0-9a-zA-Z ]+", "");` is removing all chars other than ASCII digits/letters and space. I do not know if it is expected. However, if you need to remove just the combining marks, I'd use `Regex.Replace(whatToSearch, @"\p{M}+", "");` – Wiktor Stribiżew Mar 14 '17 at 08:25

1 Answers1

1

Not clear from your question, but most probable cause is this line:

|| p.Name.RemoveDiacritics().Contains(whatToSearch)

I think this code is contacting to the database to fetch products based on the query and translator cannot find SQL analogue to RemoveDiacritics() functions.

EDIT:- Sure this will be a lot slower if it works, but lets try anyway:

if (!string.IsNullOrWhiteSpace(whatToSearch))
{
    //I've added call to ALL to fetch all products and then filter on 
    //code side. 
    products = UCommerce.EntitiesV2.Product.All().Where(p =>
            p.VariantSku == null && p.DisplayOnSite &&
            (
                p.Sku.Contains(whatToSearch)
                || p.Name.RemoveDiacritics().Contains(whatToSearch)
                || p.ProductDescriptions.Any(
                    d => d.DisplayName.Contains(whatToSearch)
                         || d.ShortDescription.Contains(whatToSearch)
                         || d.LongDescription.Contains(whatToSearch)
                )
            )
    );
}
TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
  • Yes, exactly. I need to match whatToSearch value with p.Name. So I am removing the accents from both the strings. If you can see above in the code, I have already removed them from whatToSearch as well. But when I am doing the same inside the loop, it is giving an exception. – Harsheet Mar 14 '17 at 01:46
  • Is there any other way of doing this – Harsheet Mar 14 '17 at 01:46
  • If I am doing like this inside the loop. I get an exception {"System.String Replace(System.String, System.String, System.String)"} Regex.Replace(nonSpacingMarkRegex.Replace(p.Name.Normalize(NormalizationForm.FormD), string.Empty), @"[^0-9a-zA-Z]+", "").Contains(whatToSearch) – Harsheet Mar 14 '17 at 01:51
  • This does not look like exception. Can you wrap it into `try-catch` block and give the error message (from `InnerException`s as well if there are any)? – TheVillageIdiot Mar 14 '17 at 01:58
  • This is coming from catch block only – Harsheet Mar 14 '17 at 02:09
  • Well, I don't have *ucommerce* setup but I'm sure ultimately reason is the same. I tried with `linq-to-sql` and it gives this error: `Method 'System.String RemoveDiacritics(System.String)' has no supported translation to SQL.`. The error message you are showing looks like from ucommenrce's translator. – TheVillageIdiot Mar 14 '17 at 02:17
  • Moreover, I think the source of your `RemoveDiacritics` has in-memory (C#) collection which is being used for selection. http://stackoverflow.com/questions/7418624/linq-where-ignore-accentuation-and-case – TheVillageIdiot Mar 14 '17 at 02:20
  • ok, is there any other way of doing this. I want to remove special chars and convert the accents into normal chars in both the strings, i.e what is being search and from where it is being searched. – Harsheet Mar 14 '17 at 02:24
  • I think we cannot have Find() with All(). You code will never work – Harsheet Mar 16 '17 at 02:41
  • Try get `Where` as `All` will return a collection. – TheVillageIdiot Mar 16 '17 at 02:43
  • but whatever we use, it will not give the expected result. – Harsheet Mar 16 '17 at 03:17
  • well I'm afraid without the data and code setup, I can't help much :( – TheVillageIdiot Mar 16 '17 at 03:18
  • I used collation on DisplayName column in the table. And it is working fine. – Harsheet Mar 21 '17 at 03:39