C#, dynamic linq error No applicable method 'Contains' exists in type 'String'

c# dynamic-linq linq

Question

I've got a list of things like this (I am using .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" },
};

I'm now attempting a Linq search inside the list. This is operating as anticipated.

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

This also works as anticipated when using Dynamic Linq.

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

However, the dynamic fails when attempting to utilize case (in)sensitive.

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

The mistake is

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

This was my first try at creating a Contains() extension.

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

It would seem that Dynamic Linq is ignorant of my extension. According to this, I found https://social.msdn.microsoft.com/Forums/en-US/39763339-1700-486f-9800-badd257e921e/custom-extension-methods-and-dynamic-linq-dynamic-expression-api?forum=linqprojectgeneral.

that it is difficult for Dynamic Linq to employ (static) extensions.

then either:

  1. transform extension using a standard procedure. However, how do I go about doing this for each ToString() call? Should I create a function in MyObject and then use Linq with certain objects?

  2. Adapt the Dynamic Library code to take (my)static extensions that are hard coded in.

  3. Other recommendations?

I could use a straightforward if/else for case sensitive with two dynamics, but because my program uses some intricate filtering, I wish to address the problem dynamically.

I'm grateful in advance.

1
0
11/21/2018 3:09:14 PM

Popular Answer

I would advise having the caller pass a predicate if your application requires the ability to use dynamic filters.

Unit testing is made simpler and issues may be separated as a result.

Furthermore, when the caller provides a predicate, there is no requirement for an IF/ELSE expression.

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

var tmp = test.Select(p => p.Name).Where(predicate);
1
11/21/2018 3:38:07 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow