Динамическая библиотека (System.Linq.Dynamic) SQL LIKE Оператор - PullRequest
0 голосов
/ 16 ноября 2018

Кто-то разместил подобный вопрос здесь Как динамическая библиотека (System.Linq.Dynamic) поддерживает LIKE Operator?

Но это не совсем то, что я хочу. Оператор Contains , упомянутый в этом посте, делает это только в SQL "% SOMETHING%" . Но оператор LIKE в SQL может сделать это "SOME% THING" . Есть ли аналогичный оператор для Dynamic LINQ? Если нет, есть ли решение для этого? Может быть с Regex? Также есть подстановочный знак одного символа? Например. «SOM $ THING» возвращает «SOMETHING» или «SOM3THING»

Редактировать: я разрабатываю приложение WPF, которое должно читать файлы журнала в формате XML. Каждый элемент содержит 34 поля. Поэтому вместо того, чтобы писать очень длинный WHERE, я использовал System.Reflection.PropertyInfo для итерации каждого поля, чтобы написать запрос, а затем использовать System.Linq.Dynamic для его выполнения.

Edit2: я отредактировал код, чтобы он был более читабельным для зрителей.

Вот код:

Пример 1: prop.Name = "FirstName", paramterString = "Ke% in", возвращает "Кевин", «Кельвин» ... Пример 2: prop.Name = "FirstName", paramterString = "Ke $ in", возвращает "Кевин", "Келин" ...

var query = "";
StringBuilder sb = new StringBuilder();
foreach (var prop in stringProps)
{
    sb.Append($"({prop.Name} != null And {prop.Name}.Contains({parameterString})");
}
query = sb.ToString().Substring(0, sb.Length - 4);
filteredData = filteredData.Where(query);

Одним из требований является реализация оператора SQL LIKE, чтобы пользователи могли использовать что-то подобное, чтобы получить желаемый результат: FirstName LIKE 'SOME% THING'

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Можете ли вы попробовать, если Like функциональность в System.Linq.Dynamic.Core работает для вас?

Пример кода:

var dynamicFunctionsLike1 = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");

Полный пример см. В ConsoleAppEF2.1.1 / Program.cs

0 голосов
/ 19 ноября 2018

Поскольку в библиотеке Dynamic Linq нет оператора LIKE, я создал свою собственную версию. Код не очень красивый, но он работает. Надеюсь, кто-то может оптимизировать его или предложить лучший способ сделать это.

public string ParseWildcardInParameterString(string parameter, string propertyName)
{
    string stringWithWildcard = parameter;
    if (parameter.Contains("%") || parameter.Contains("$"))
    {
        stringWithWildcard = parameter;
        string[] substrings = parameter.Split(new Char[] { '%', '$' }, StringSplitOptions.RemoveEmptyEntries);
        string[] wildcards = ParseWildcards(parameter);
        if (substrings.Any())
        {
            StringBuilder sb = new StringBuilder();
            int substringsCount = substrings.Length;
            for (int i = 0; i < substringsCount; i++)
            {
                if (!substrings[i].EndsWith("\\"))
                {
                    int index = parameter.IndexOf(substrings[i]);
                    if (i < substringsCount - 1)
                    {
                        index = parameter.IndexOf(substrings[i + 1], index + 1);
                        if (index > -1)
                        {
                            string secondPart = wildcards[i].Equals("%") ?
                                $"{propertyName}.IndexOf(\"{substrings[i + 1]}\", {propertyName}.IndexOf(\"{substrings[i]}\") + \"{substrings[i]}\".Length) > -1" :
                                $"{propertyName}.IndexOf(\"{substrings[i + 1]}\", {propertyName}.IndexOf(\"{substrings[i]}\") + \"{substrings[i]}\".Length + 1) == {propertyName}.IndexOf(\"{substrings[i]}\") + \"{substrings[i]}\".Length + 1";
                            sb.Append($"({propertyName}.IndexOf(\"{substrings[i]}\") > -1 And {secondPart}) And ");
                        }
                    }
                }
            }
            stringWithWildcard = sb.Remove(sb.Length - 5, 5).Append(") Or ").ToString();
        }
    }
    return stringWithWildcard;
}

private string[] ParseWildcards(string parameter)
{
    IList<string> wildcards = new List<string>();
    foreach (var chararcter in parameter.ToCharArray())
    {
        if (chararcter.Equals('%') || chararcter.Equals('$'))
        {
            wildcards.Add(chararcter.ToString());
        }
    }
    return wildcards.ToArray();
}
...