尝试开发新的扩展方法 [英] Trying to develop a new extension method

查看:54
本文介绍了尝试开发新的扩展方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Entity Framework,并且开发了此扩展方法:

I'm using the Entity Framework and I developed this extension method:

public static IQueryable<TResult> Like<TResult>(this IQueryable<TResult> query, Expression<Func<TResult, string>> field, string value) 
{
    var expression = Expression.Lambda<Func<TResult, bool>>(
        Expression.Call(field.Body, typeof(string).GetMethod("Contains"),
        Expression.Constant(value)), field.Parameters);

    return query.Where(expression);
}

如果我这样使用,则此代码可以正常工作:

this code work correctly if I use it like this:

var result = from e in context.es.Like(r => r.Field, "xxx")
             select e

现在,我需要以编程方式调用此扩展方法:

Now I need to call this extension method programmatically:

public static IQueryable<TSource> SearchInText<TSource>(this IQueryable<TSource> source, string textToFind)
{
    // Collect fields
    PropertyInfo[] propertiesInfo = source.ElementType.GetProperties();
    List<string> fields = new List<string>();
    foreach (PropertyInfo propertyInfo in propertiesInfo)
    {
        if (
            (propertyInfo.PropertyType == typeof(string)) ||
            (propertyInfo.PropertyType == typeof(int)) ||
            (propertyInfo.PropertyType == typeof(long)) ||
            (propertyInfo.PropertyType == typeof(byte)) ||
            (propertyInfo.PropertyType == typeof(short))
            )
        {
            fields.Add(propertyInfo.Name);
        }
    }

    ParameterExpression parameter = Expression.Parameter(typeof(TSource), source.ElementType.Name);
    Expression expression = Expression.Lambda(Expression.Property(parameter, typeof(TSource).GetProperty(fields[0])), parameter);
    Expression<Func<TSource, string>> field = Expression.Lambda<Func<TSource, string>>(expression, parameter);

    return source.Like(field, textToFind);
}

现在此代码不起作用! 我需要了解如何声明Like扩展方法的字段".

Now this code doesn't work! I need to understand how to declare the "field" of the Like extended methods.

Expression<Func<TSource, string>> field = Expression.Lambda<Func<TSource, string>>(expression, parameter);

在运行时,我收到以下错误消息:每次未恢复到"System.String"状态时,就无法使用utilizzare对系统'System.Func`2 [TestMdf.Equipment,System.String]进行压缩

At runtime I receive this error: Impossibile utilizzare un'espressione di tipo 'System.Func`2[TestMdf.Equipment,System.String]' per un tipo restituito 'System.String'

推荐答案

这是我的第一个版本:

public static IQueryable<TSource> SearchInText<TSource>(this IQueryable<TSource> source, string textToFind)
{
    if (textToFind.Trim() == "")
    {
        return source;
    }
    string[] textToFindList = textToFind.Replace("'", "''").Split(' ');

    // Collect fields
    PropertyInfo[] propertiesInfo = source.ElementType.GetProperties();
    List<string> fieldList = new List<string>();
    foreach (PropertyInfo propertyInfo in propertiesInfo)
    {
        if (
            (propertyInfo.PropertyType == typeof(string)) ||
            (propertyInfo.PropertyType == typeof(int)) ||
            (propertyInfo.PropertyType == typeof(long)) ||
            (propertyInfo.PropertyType == typeof(byte)) ||
            (propertyInfo.PropertyType == typeof(short))
            )
        {
            fieldList.Add(propertyInfo.Name);
        }
    }

    ParameterExpression parameter = Expression.Parameter(typeof(TSource), source.ElementType.Name);
    MethodInfo concatMethod = typeof(String).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });

    var spaceExpression = Expression.Constant(" ");
    var concatenatedField = BinaryExpression.Add(spaceExpression, Expression.MakeMemberAccess(parameter, typeof(TSource).GetProperty(fieldList[0])), concatMethod);

    for (int i = 1; i < fieldList.Count; i++)
    {
        concatenatedField = BinaryExpression.Add(concatenatedField, spaceExpression, concatMethod);
        concatenatedField = BinaryExpression.Add(concatenatedField, Expression.MakeMemberAccess(parameter, typeof(TSource).GetProperty(fieldList[i])), concatMethod);
    }

    concatenatedField = BinaryExpression.Add(concatenatedField, spaceExpression, concatMethod);
    var fieldsExpression = Expression.Call(concatenatedField, "ToUpper", null, null);

    var clauseExpression = Expression.Call(
        fieldsExpression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
        Expression.Constant(textToFindList[0].ToUpper())
        );

    if (textToFindList.Length == 1)
    {
       return source.Where(Expression.Lambda<Func<TSource, bool>>(clauseExpression, parameter));
    }

    BinaryExpression expression = Expression.And(Expression.Call(
            fieldsExpression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
            Expression.Constant(textToFindList[1].ToUpper())
            ), clauseExpression);
    for (int i = 2; i < textToFindList.Length; i++)
    {
        expression = Expression.And(Expression.Call(
            fieldsExpression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
            Expression.Constant(textToFindList[i].ToUpper())
            ), expression);
    }

    return source.Where(Expression.Lambda<Func<TSource, bool>>(expression, parameter));

}

我将进行修改以管理一些规则,例如短语" +和-运算符.

I will modify to manage some rules like "phrase" + and - operator.

这篇关于尝试开发新的扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆