C #, динамическая ошибка linq Нет подходящего метода Contains в типе String - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть список таких объектов (я использую .NET 3.5)

public class MyObjects
{
    public object Name { get; set; }
    public bool Case { get; set; }
}

List<MyObjects> test = new List<MyObjects> { 

    new MyObjects { Name = "one" },
    new MyObjects { Name = "two" },
    new MyObjects { Name = "three" },
    new MyObjects { Name = "four" },
    new MyObjects { Name = "one1" },
    new MyObjects { Name = "two1" },
    new MyObjects { Name = "three1" },
    new MyObjects { Name = "four1" },
    new MyObjects { Name = "one2" },
    new MyObjects { Name = "two2" },
    new MyObjects { Name = "three2" },
    new MyObjects { Name = "four2" },
};

Теперь я пытаюсь искать в списке с помощью Linq.Это работает как ожидалось

var tmp = test
    .Select(p => p.Name)
    .Where(x => x.ToString().Contains("One", StringComparison.InvariantCultureIgnoreCase))
    ;

Используя Dynamic Linq, это также работает как ожидалось

var dtmp = test.AsQueryable()
    .Select(p => p.Name)
    .Where("ToString().Contains(@0)", "one")
    ;

Однако, при попытке использовать регистр (без учета), динамический сбой.

var dtmp2 = test.AsQueryable()
    .Select(p => p.Name)
    .Where("ToString().Contains(@0, @1)", "one", StringComparison.InvariantCultureIgnoreCase)
    ;

Ошибка:

No applicable method 'Contains' exists in type 'String'

Моя первая попытка была написать расширение Contains (), подобное этому

public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    return source.IndexOf(toCheck, comp) >= 0;
}

Похоже, что Dynamic Linq не знает омое расширение.Я обнаружил (в соответствии с этим) https://social.msdn.microsoft.com/Forums/en-US/39763339-1700-486f-9800-badd257e921e/custom-extension-methods-and-dynamic-linq-dynamic-expression-api?forum=linqprojectgeneral

, что Dynamic Linq не может использовать (статическое) расширение очень легко.

Так что либо:

  1. Преобразовать расширение обычным способом.Тем не менее, как я могу сделать это для каждого ToString (), это возможно, или я должен написать метод в MyObject, а затем использовать linq с конкретными объектами?

  2. Изменить код динамической библиотеки для принятиястатически (мои) статические расширения.

  3. Другие предложения?

Примечание: я мог бы использовать простой if / else для чувствительных к регистру символов с двумядинамика, но я предпочитаю решать динамический путь, так как мое приложение использует некоторую сложную фильтрацию.

Заранее спасибо,

Ответы [ 2 ]

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

Вы пытались использовать System.Linq.Dynamic.Core , потому что кажется, что эта библиотека может обрабатывать ваш пример кода c #.

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

Если вашему приложению нужны возможности динамического фильтра, я бы рекомендовал вызывающей стороне передать предикат.

Это позволяет разделить проблемы и упростить юнит-тестирование.

Кроме того, нет необходимости в операторе IF / ELSE, когда вызывающая сторона передает предикат.

var predicate = new Predicate<string>(str => str.Contains("one"));

var tmp = test.Select(p => p.Name).Where(predicate);
...