Hi,
Sometimes whether to use StartsWith, EndsWith or Contains in LINQ like clauses, is determined by the search value. For example if the search value is "S%" a startswith should be used. In these cases an extension of IQuerable like the one below which I found in stack-overflow, would be handful.
It is supposed to work like this:
LinqMetaData metaData = new LinqMetaData();
var q = from p in metaData.Patient
where p.Like(x=>x.Name, "S%")
select p;
Unfortunately it doesn't work with LLBL linq. If you have any idea why please let me know:
using LinqExpression = System.Linq.Expressions.Expression;
public static class LinqEx
{
private static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains");
private static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
private static readonly MethodInfo EndsWithMethod = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
public static System.Linq.Expressions.Expression<Func<TSource, bool>> LikeExpression<TSource, TMember>(System.Linq.Expressions.Expression<Func<TSource, TMember>> property, string value)
{
var param = LinqExpression.Parameter(typeof(TSource), "t");
var propertyInfo = GetPropertyInfo(property);
var member = LinqExpression.Property(param, propertyInfo.Name);
var startWith = value.StartsWith("%");
var endsWith = value.EndsWith("%");
if (startWith)
value = value.Remove(0, 1);
if (endsWith)
value = value.Remove(value.Length - 1, 1);
var constant = LinqExpression.Constant(value);
LinqExpression exp;
if (endsWith && startWith)
{
exp = LinqExpression.Call(member, ContainsMethod, constant);
}
else if (startWith)
{
exp = LinqExpression.Call(member, EndsWithMethod, constant);
}
else if (endsWith)
{
exp = LinqExpression.Call(member, StartsWithMethod, constant);
}
else
{
exp = LinqExpression.Equal(member, constant);
}
return LinqExpression.Lambda<Func<TSource, bool>>(exp, param);
}
public static IQueryable<TSource> Like<TSource, TMember>(this IQueryable<TSource> source, System.Linq.Expressions.Expression<Func<TSource, TMember>> parameter, string value)
{
return source.Where(LikeExpression(parameter, value));
}
private static PropertyInfo GetPropertyInfo(LinqExpression expression)
{
var lambda = expression as LambdaExpression;
if (lambda == null)
throw new ArgumentNullException("expression");
MemberExpression memberExpr = null;
switch (lambda.Body.NodeType)
{
case ExpressionType.Convert:
memberExpr = ((UnaryExpression)lambda.Body).Operand as MemberExpression;
break;
case ExpressionType.MemberAccess:
memberExpr = lambda.Body as MemberExpression;
break;
}
if (memberExpr == null)
throw new InvalidOperationException("Specified expression is invalid. Unable to determine property info from expression.");
var output = memberExpr.Member as PropertyInfo;
if (output == null)
throw new InvalidOperationException("Specified expression is invalid. Unable to determine property info from expression.");
return output;
}
}