I’m building a LINQ query dynamically based on user input, and I want to handle the case where the user is searching for a record r based on a string str and field foo where str.Contains(r.foo). Now, the reverse (r.foo.Contains(str)) is simple, but LINQ is giving me grief about doing it the other way.
Here’s what I have so far:
private Expression SqlNotIn(Expression left, Expression right)
{
return Expression.Equal(
Expression.Call(
null,
typeof(SqlFunctions).GetMethod("CharIndex", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null),
new[] { right, left }
),
Expression.Constant(0)
);
}
This is supposed to take an Expression left, which is the property accessor, and Expression right, which is a constant of the string to search in, and return an Expression representing (essentially) (SqlFunctions.CharIndex(right, left) == 0). When I run this, I get “The binary operator Equal is not defined for the types ‘System.Nullable1[System.Int32]' and 'System.Int32'." Explicitly casting the0toint?` with an as expression seemed to cause LINQ to run the query early.
Is there a simple way to do this?
EDIT:
private Expression SqlNotIn(Expression left, Expression right)
{
return Expression.Equal(
Expression.Call(
right,
typeof(string).GetMethod("IndexOf", new[] { typeof(string) }),
new[] { left }
),
Expression.Constant(-1)
);
}
This works, but the SQL it generates looks like this:
(CASE
WHEN DATALENGTH([t0].[Destination]) = 0 THEN 0
ELSE CHARINDEX([t0].[Destination], @p0) - 1
END) = @p1
I’d be happy to use CharIndex if I could.
You can try to convert first part to
int, or second part toint?withExpression.Converthttp://msdn.microsoft.com/en-us/library/bb292051.aspxFor example. Untested.
By the way you could use a
string inputValueas second parameter, and use it withExpression.Constant(inputValue)EDIT :
EDIT 2: