Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy do these three pieces of LINQ code produce different (or erroneous) results?
    primarykey
    data
    text
    <p>Here is some sample data:</p> <pre><code>List&lt;Book&gt; books = new List&lt;Book&gt;() { 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's game", Pages = 404}, new Book(){Title = "the sphere", Pages = 657} }; </code></pre> <p><strong>Background:</strong></p> <p>The above uses a simplified version of a Book class. It would, of course, contain many fields. My end goal is to allow the user to perform an 'advanced' search allowing the user to specify <em>any</em> field and further allow the user to specify keywords using boolean algebra for a particular field.</p> <p>eg: In a title search text box: the + (cake | pastry) + ~demon</p> <p>The above would mean: Find all books that, in the title, have the words 'the', either of 'cake' or 'pastry', and does not have the word 'demon'.</p> <p><strong>Problem:</strong></p> <p>Baby steps will lead to the final solution. So I initially had the following code:</p> <pre><code>List&lt;Func&lt;Book, bool&gt;&gt; fs = new List&lt;Func&lt;Book, bool&gt;&gt;() { b =&gt; b.Title.Contains("me"), b =&gt; 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); } </code></pre> <p>The above code works fine. It looks for books that contain 'the' AND 'me' in the title.</p> <p><strong>Phase 2</strong></p> <p>Now the above filter is of type Func&lt;<strong>Book</strong>, bool>. That class will be an Entity Framework generated class and I don't want to use in my UI layer where the search phrase will be input and search filters will be generated to be passed on to the BLL.</p> <p><strong>So I have the following three attempts:</strong></p> <pre><code>var q = from b in books select b; List&lt;Func&lt;string, bool&gt;&gt; filters = new List&lt;Func&lt;string, bool&gt;&gt;() { s =&gt; s.Contains("me"), s =&gt; s.Contains("the"), }; </code></pre> <hr> <pre><code>//This works... for (int i = 0; i != filters.Count; ++i) { Func&lt;string, bool&gt; daF = filters[i]; q = q.Where(b =&gt; (daF(b.Title))); } </code></pre> <hr> <pre><code> //This produces an exception... //Due to index in query? // for (int i = 0; i != filters.Count; ++i) // { // q = q.Where(b =&gt; ((filters[i])(b.Title))); // } </code></pre> <hr> <pre><code> //This runs but doesn't produce the proper output // foreach (Func&lt;string, bool&gt; filter in filters) // q = q.Where(b =&gt; filter(b.Title)); </code></pre> <hr> <pre><code>foreach (Book b in q) { Console.WriteLine("Title:\t\t{0}\nPages:\t\t{1}\n", b.Title, b.Pages); } </code></pre> <p>The first commented-out piece fires an indexer out of range exception stating that the value of i is 2.</p> <p>The second commented-out piece runs and produces output, but it prints out FOUR of the 5 books... all EXCEPT the book titled "ender's game". That's not right...</p> <p>So, reading over my post, I see that I could not reign in my bad habit of explaining every little detail...</p> <p>So there you go. Please explain why the differing outputs. And I guess you could hint on likely improvements to my current 'solution'.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload