简体   繁体   中英

Trouble with PredicateBuilder

I'm having trouble using PredicateBuilder to dynamically add "Or Where" clauses to a LINQ statement. I'll explain what I'm trying to accomplished first.

I have an inverted index that stores keywords from the titles of a bunch of links. I'm using one so I can quickly search through these links based on these keywords. The inverted index is of type

Dictionary<string, List<VerifiedUrl>>

So basically every word is associated to a list of URLs containing that word.

The next stage I'm at is making the inverted index searchable. So when I search for "the blue", I'm returned all the links associated with the key "the" or "blue". After a few Google searches, it seemed like the best way to dynamically add "Or Where" clauses to a LINQ statement was through the PredicateBuilder class. I'm having trouble with the last step where I use the predicate that I've built.

var invertedIndex = new Dictionary<string, List<VerifiedUrl>>();

//the invertedIndex is built and filled here. Now I am trying to search through it.

Console.WriteLine("\nEnter words to see if there are matches");
string query = Console.ReadLine();
Console.WriteLine();

string[] words = query.Split(',', ' '); 

//the predicate I'll be building. I'm not positive it is of the correct type. I've assumed that it should be of the same type as the Dictionary type in the inverted index
var predicate = PredicateBuilder.False<KeyValuePair<string, List<VerifiedUrl>>>();

foreach (string w in words)
{
    string temp = w;
    predicate = predicate.Or(p => p.Key == temp);
}
//this is the line that generates the syntax error.
test = invertedIndex.Where(predicate);

I get an error on the.Where statement. Hovering over the.Where displays "The type arguments cannot be inferred from the usage. Try specifying the type arguments exactly."

I tried changing:

var predicate = PredicateBuilder.False<KeyValuePair<string, List<VerifiedUrl>>>();

to

Expression<Func<KeyValuePair<string, List<VerifiedUrl>>, bool>> predicate = PredicateBuilder.False<KeyValuePair<string, List<VerifiedUrl>>>();

but this had no effect. In the error console I actually get different errors:

Error   1   Instance argument: cannot convert from 'System.Collections.Generic.Dictionary<string,System.Collections.Generic.List<InvertedIndexConsoleApp.VerifiedUrl>>' to 'System.Linq.IQueryable<System.Collections.Generic.KeyValuePair<string,System.Collections.Generic.List<InvertedIndexConsoleApp.VerifiedUrl>>>'   c:\users\josh\documents\visual studio 2010\Projects\InvertedIndexConsoleApp\InvertedIndexConsoleApp\Program.cs  79  25  InvertedIndexConsoleApp

Error   2   'System.Collections.Generic.Dictionary<string,System.Collections.Generic.List<InvertedIndexConsoleApp.VerifiedUrl>>' does not contain a definition for 'Where' and the best extension method overload 'System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,bool>>)' has some invalid arguments c:\users\josh\documents\visual studio 2010\Projects\InvertedIndexConsoleApp\InvertedIndexConsoleApp\Program.cs  79  25  InvertedIndexConsoleApp

the problem that.Where argument must be a Func, but PredicateBuilder.Or returns Expression< Func<..>>. Try this

test = invertedIndex.Where(predicate.Compile());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM