Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 参数化Linq表达式帮助_C#_Linq_Linq To Entities_Expression Trees - Fatal编程技术网

C# 参数化Linq表达式帮助

C# 参数化Linq表达式帮助,c#,linq,linq-to-entities,expression-trees,C#,Linq,Linq To Entities,Expression Trees,我想做一个签名如下的方法: Expression<Func<TSource, bool>> CreatePropertyFilter<TSource>(Expression<Func<TSource, string>> selector, string value, TextMatchMode matchMode); Expression<Func<string, bool>> comparerExpressi

我想做一个签名如下的方法:

Expression<Func<TSource, bool>> CreatePropertyFilter<TSource>(Expression<Func<TSource, string>> selector, string value, TextMatchMode matchMode);
Expression<Func<string, bool>> comparerExpression;

switch (matchMode)
{
    case TextMatchMode.StartsWith:
       comparerExpression = p => p.StartsWith(value);
       break;
    case TextMatchMode.EndsWith:
       comparerExpression = p => p.EndsWith(value);
       break;
    case TextMatchMode.Contains:
       comparerExpression = p => p.Contains(value);
       break;
    default:
       comparerExpression = p => p.Equals(value);
       break;
}

var equalityComparerParameter = Expression.Parameter(typeof(IncomingMail), null);
var equalityComparerExpression = Expression.Invoke(comparerExpression, Expression.Invoke(selector, equalityComparerParameter));
var equalityComparerPredicate = Expression.Lambda<Func<IncomingMail, bool>>(equalityComparerExpression, equalityComparerParameter);
问题是LINQ2实体不支持调用表达式

有什么建议吗


谢谢

基本上,给定一个选择器:

input => input.Member
您当前正在构造一个谓词表达式,如:

input => selector(input).Method(value)
相反,通过使用选择器表达式的主体(a
MemberExpression
)来“展开”选择器表达式,以构造如下内容:

input => input.Member.Method(value) 
这看起来像:

private static Expression<Func<TSource, bool>> CreatePropertyFilter<TSource>
    (Expression<Func<TSource, string>> selector, 
     string value, 
     TextMatchMode matchMode)
{
    // Argument-checking here.    

    var body = selector.Body as MemberExpression;

    if (body == null)
        throw new ArgumentException("Not a MemberExpression.");    

    // string.StartsWith / EndsWith etc. depending on the matchMode.
    var method = typeof(string)
                 .GetMethod(GetMethodName(matchMode), new[] { typeof(string) });

    // input.Member.method(value)
    var compEx = Expression.Call(body, method, Expression.Constant(value));

    // We can reuse the parameter of the source.
    return Expression.Lambda<Func<TSource, bool>>(compEx, selector.Parameters);
}

谢谢你,安尼!这正是我要找的,工作起来很有魅力!我对lambda表达式的世界太新鲜了。
// I really don't like this enum.
// Why not explicitly include Equals as a member?
private static string GetMethodName(TextMatchMode mode)
{
    switch (mode)
    {
        case TextMatchMode.StartsWith:
            return "StartsWith";

        case TextMatchMode.EndsWith:
                return "EndsWith";

        case TextMatchMode.Contains:
            return "Contains";

        default:
            return "Equals";
    }    
}