I am trying to implement a wildcard search Functionlity for (*,?) using LINQ to SQL. As of now, I want to try it using Regular expression as the code we write will be short and easily manageable. Here is what I have
string kw=_keyword.Replace("*",".*").Replace("?",".");
var predicate = PredicateBuilder.True<DAL.RequestAttribute>();
Regex reg=new Regex("^"+kw+"$");
predicate=predicate &&(reg.IsMatch(ra=>ra.AttributeValue));
So, here it gives a compilation error as "Cannot convert lambda expression to type 'string' because it is not a delegate type"
Though some workarounds if I make it compile and run, I get this runtime Error
"Method 'Boolean IsMatch(System.String)' has no supported translation to SQL."
So, I have two Questions here
1. Am I thinking in right lanes to implement my wildcard using Regular Expressions? if not, which is more efficient way to do this?
2. How to resolve this error .
Thanks
You could mimic SQL's LIKE operator by using SqlMethods.Like: https://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.like%28v=vs.110%29.aspx.
Just be sure to use the appropriate wildcards/tokens: https://msdn.microsoft.com/en-us/library/ms179859.aspx.
Update:
You cannot use regular expressions with simple SQL. Since you are essentially building a SQL statement via LINQ, the same rule applies. Though, it's still not quite clear where you are tapping into LINQ with the sample code you've provided.
I would typically expect to see something like the following:
var results =
from Something in SomeLinqContext
where SqlMethods.Like(Something.Value, kw);
After some research I found an answer to my question. Thanks to Ventaur for the Suggestion. the solution is on similar lines but just a bit different. PFB the code for it
string kw=_keyword.Replace("*","%").Replace("?","_");
var predicate = PredicateBuilder.True<DAL.RequestAttribute>();
predicate = (ra => SqlMethods.Like(ra.AttributeValue, kw) && <Any other boolean conditions>
Therefore it boils down to how to make an expression out of SQLMethods.like method using our predicate builder class.
Related
How can I validate NCalc expression? I want to use NCalc for evaluating if/else/endif condition in my simple custom language for defining sequence of steps. Main program will provide some parameters for conditions. Sequences are defined by user, so my parser have to validate if condition is ok and uses only provided parameters.
I already tried some tests, but don't know how to do this. HasErrors() methods doesn't check used parameters. Evaluate() uses optimalizations, so if I write expression "true or XXXX", it will end with true result and doesn't find out that XXXX parameter is invalid. How can I do this? I want to validate it already in compilation time.
Thanks.
I found the answer in this question (marked as answer), maybe I should have used also other keywords in google.
Get the parameters in an expression using NCalc
I tested that solution with my visitor based on LogicalExpressionVisitor and it's working. But, theoretically, maybe it's not the same as validation, because I get the list of parameter names, but from parsed expression, without supplied parameter values. So maybe the expression can fail in case of special "bad" parameter values supplied for evaluation. But it's enough for my case, I know all parameters I will supply to expression, so for me it's enough to get just parameter names.
I need to pass an expression from a WinForms client to a WebApi. I have the following expression:
var results = somelist.Select(p => p.Id).ToList<int>();
Expression<Func<MyObj, bool>> myexp = x => results.Contains(x.Id);
I then simply did:
var str = myexp.Body.ToString();
However, in this particular example, the expression body looks like this:
value(MyApp.MyForm+<>c__DisplayClass41_0).results.Contains(x.Id)
Which obviously will not work when translating back the string to an expression server-side.
Is there a way to reduce, compile, whatever the expression in a better way? Or should I use 3rd party solutions like Remote.Linq or Serialize.Linq?
It depends on what you need to do with the expression on the server side.
If you really only need a string representation you might want to implement an ExpressionVisitor. However, this may require quite some effort, depending the kind of expressions you need to support.
In case you want to convert back to a proper expression tree and execute the expression on server side, it's definitely worth the have a look at Remote.Linq.
Sorry if this has been answered - I have read at least 20 questions that answer an almost identical question but they're all with slightly different circumstances or I can't get them to work.
That's also despite the fact what I want is far more simple! :(
All I want to do is return all the elements of a string array that start with "ABC".
So {"ABC_1", "ABC_2", "ABC_3", "123_1", "ABC_4"}
Will return {"ABC_1", "ABC_2", "ABC_3", "ABC_4"}
Using Linq with Lambda Expressions:
So the logic would be similar to the following:
FilteredArray = StringArray.Where(String.StartsWith("ABC"));
Everytime I try something similar to the above it returns no values.
Thank you in advanced for your help and apologies in advanced for not being able to solve this independently.
P.S If you know of a link that would provide me with a good tutorial on Linq with Lambda Expressions that would be greatly appreciated.
If you want to make an array from an array, you need to use ToArray. You also need to get your LINQ syntax right:
// This assumes that FilteredArray is declared as String[]
FilteredArray = StringArray.Where(str => str.StartsWith("ABC")).ToArray();
Note that Where is not all-caps because identifiers in C# are case-sensitive. Also note the use of the lambda syntax inside the Where method.
I'm not actually sure the original example would compile? Your missing the lambda syntax. This will work correctly. Basically you need to specify the input parameter for the where clause (each of the strings in the array) this is x. Then you do you're string startswith check on that.
var filtered = StringArray.Where(x => x.StartsWith("ABC"));
You need to use the correct syntax in your lambda expression like this
var FilteredArray = StringArray.Where(x => x.StartsWith("ABC")).ToArray();
If you want to learn about Linq expressions then here is a very good solution available for you 101 Linq Samples
I have a search criteria stored in a string:
string Searchstr = "(r.Value.Contains("PwC") || (r.Value.Contains("Canadian") && r.Value.Contains("thrive"))) || (r.Value.Contains("Banana") && r.Value.Contains("Gayle"))"
I want to use this in a If statement to check the values:
if(searchstr)
{
then do this....
}
but the if should have a searchstr as boolean.
How to convert this to boolean?
EDIT: The requirement is to give search criteria dynamically in a text box in the following format - "PwC OR (Canadian AND thrive)".
Which will be used to search an XML file.
Therefore I have loaded an XML file and want to have a Where condition in LINQ for which I need to use Dynamic LINQ but string is not allowed in that and also I have some braces to deal with.
Thinking of that I have taken the resultset from the XML(The tag value which i need to search)
var selectedBook = from r in document.Root.Descendants("Archives").Elements("Headline").Elements("Para")
select r;
and would ideally like to try something like:
var query=selectedbook.Where(searchstr)
OR
if(searchstr){....then do this}
You will need to do a bit of work to make this happen, but it is possible.
You should have a look at the dynamic LINQ library. This allows you to specify LINQ conditions (and other clauses) as strings and execute them just like LINQ operators.
Start with the explanation on ScottGu's blog and follow the links:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
I'm assuming the string is going to reference only a specific set of objects (r or r.Value in this case, for example - or anything else you want, as long as you know it beforehand). If this is the case, then:
Create a delegate that takes the objects (that may be referenced) as parameters
and returns a bool, as you want.
Programmatically write a small C# source file in memory that defines the query
as the body of a method (with a fixed name, preferably) that conforms to the delegate specified above.
Use the CSharpCodeProvider class to compile an assembly
with your custom function that returns the bool you want.
Run the dynamically written and compiled code from your main program.
Well as you may guess it is not going to be straight forward but at the same time it is not as hard a problem as it seems
You can perform a few steps to get what you want:
Get the search expression as input (for e.g. "PwC OR (Canadian AND thrive)")
Write an extension method on XElement that returns true and takes the search criteria as input. You will then be able to use
var selectedBook = from r in
document.Root.Descendants("Archives").Elements("Headline").Elements("Para")
where r.SatisfiesCriteria(searchCriteria)
select r;
Write a parser class that parses searchCritera and stores it in parsed format. (for e.g. you can convert it into postfix notation). This is quite easy and you can use standard algorithm for this. For your purpose OR, AND will be operators and PwC etc. will be operands. Parenthesis will get removed as part of parsing.
Now simply invoke this parser from with in your extension method and then evaluate the postfix expression you get. This again can be done through standard stack based evaluation. Infact it would be better if you parse the criteria once and then only evaluate in where. While evaluating you need to replace the operands with r.Value.Contains
It seems like a good scenario for http://scriptcs.net/
Just started looking at the OData support for the WebAPI and for now it seems like there is alot left to do until the "querying-support" becomes truly interesting.. and thats sort of where this idea were born.. would it be possible some how to send a lambda expression as a querystring and then parse that and run it against an IEnumerable and then return the value?
The whole problem is the expression parsing and how to actually execute the parsed expression against the object.. Im quite unsure about how to do such a thing.. any ideas?.. or is there any place where I can read more about this?
Thanks in advance!
What I understood from your interest is to write your own LINQ parser. check this out: Invent your own dynamic LINQ parser
Also have a look at the discussion happening over implementation of Like operator support for OData here.