Why do these three pieces of LINQ code produce different (or erroneous) results?

Here are some sample data:

List<Book> books = new List<Book>()
{
    new Book(){Title = "artemis fowl: the time paradox", Pages = 380},
    new Book(){Title = "the lieutenant", Pages = 258},
    new Book(){Title = "the wheel of time", Pages = 1032},
    new Book(){Title = "ender game", Pages = 404},
    new Book(){Title = "the sphere",  Pages = 657}
};  

Background:

The above example uses a simplified version of the Book class. Of course, this will be many fields. My ultimate goal is to allow the user to perform an “advanced” search, allowing the user to specify any field and then allow the user to specify keywords using logical algebra for a specific field.

for example: in the header search text box: + (cake | cookie) + ~ daemon

The above would mean: to find all the books that have the words "the", "cake" or "cookies" in the title, and do not have the word "demon".

Problem:

Baby steps will lead to a final decision. Therefore, I initially had the following code:

List<Func<Book, bool>> fs = new List<Func<Book, bool>>()
{
    b => b.Title.Contains("me"),
    b => b.Title.Contains("the")
};

var q2 = from b in books select b;
foreach (var f in fs)
    q2 = q2.Where(f);

foreach (Book b in q2)
{
    Console.WriteLine("Title:\t\t{0}\nPages:\t\t{1}\n",
                      b.Title, b.Pages);
}

. , "" .

2

Func < Book, bool > . Entity Framework, , , BLL.

, :

var q = from b in books select b;

List<Func<string, bool>> filters  = new List<Func<string, bool>>()
{
    s => s.Contains("me"),
    s => s.Contains("the"),
};

//This works...
for (int i = 0; i != filters.Count; ++i)
{
    Func<string, bool> daF = filters[i];
    q = q.Where(b => (daF(b.Title)));
}     

            //This produces an exception...
            //Due to index in query?
//            for (int i = 0; i != filters.Count; ++i)
//            {
//                q = q.Where(b => ((filters[i])(b.Title)));
//            }

            //This runs but doesn't produce the proper output
//            foreach (Func<string, bool> filter in filters)
//              q = q.Where(b => filter(b.Title));

foreach (Book b in q)
{
    Console.WriteLine("Title:\t\t{0}\nPages:\t\t{1}\n",
                      b.Title, b.Pages);
}

, , 2.

, ... "-". ...

, , , ...

, . , , . , "".

+5
1

LINQ to Objects , All(). .

var query = books.Where(book => filters.All(filter => filter(book.Title)));

:

var query = from book in books
            where filters.All(filter => filter(book.Title))
            select book;

, , . - - . , , . , . .

for (int i = 0; i != filters.Count; ++i)
{
    var index = i;
    q = q.Where(b => filters[index](b.Title));
}

foreach (Func<string, bool> f in filters)
{
    var filter = f;
    q = q.Where(b => filter(b.Title));
}
+4

All Articles