Like extension in Linq

Posts   
 
    
pg71
User
Posts: 2
Joined: 19-Oct-2016
# Posted on: 19-Oct-2016 21:56:23   

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;
    }
}
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Oct-2016 08:12:35   

What LLBLGen version and runtime library version are you using? What is exactly tht doesn't work?

http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=12769

David Elizondo | LLBLGen Support Team
pg71
User
Posts: 2
Joined: 19-Oct-2016
# Posted on: 20-Oct-2016 15:42:03   

Version is 4.2.

The problem is that I cannot formulate the lamda expression inside Like method. x.Name is not provided as an option:

where p.Like(x=>x.Name, "S%")

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 20-Oct-2016 22:33:55   

The extension method is for the IQueryable not the PatientEntity.

You should use it as such:

var q = (from p in metaData.Patient
         select p).Like(x=>x.Name, "S%");