2017-09-25 46 views
2

我试图创建一个自定义的LINQ到用逗号分隔的字符串,将其转换为一个数组实体扩展方法,然后使用IEnumerable<string>.Contains产生相当于的SQL IN子句。自定义扩展方法中的LINQ EF相当于SQL“IN”的条款

很容易,当你总是知道表/实体及其列/要将此过滤器应用于属性。我们面临的挑战是,我希望能够利用这个扩展方法上的任何实体或财产。

这是多远我来:

public static IQueryable<TSource> CustomInClause<TSource>(this IQueryable<TSource> myQuery, Expression<Func<TSource, string>> colExpression, string filterCriteria) 
{ 
    string[] myArray = filterCriteria.Split(",", StringSplitOptions.RemoveEmptyEntries); 

    //Various other operations here.............. 

    if (myArray.Length > 0) 
    { 
     myQuery = myQuery.Where(b => myArray.Contains(colExpression)); 
    } 

    return myQuery; 
} 

正如你所看到的,我试图用colExpression作为一个动态的表达,这将是x => x.SomeColumn相当于其中SomeColumn可以是任意的字符串/ VARCHAR柱。

然后,我会实现这个扩展是这样的:

var q = context.SomeTable.CustomInClause(f => f.SomeColumn, someString); 

var q2 = context.OtherTable.CustomInCluse(f => f.OtherColumn, otherString); 

现在我得到这个错误:

'string[]' does not contain a definition for 'Contains' and the best extension method overload 'ParallelEnumerable.Contains>>(ParallelQuery>>, Expression>)' requires a receiver of type 'ParallelQuery>>'

我不太知道如何在这种情况下使用并行查询,或者如果有另一种解决方案。有任何想法吗?

回答

0

你必须建立Contains调用作为表达的一部分,在where子句

var myArray = filterCriteria.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries) 
       .ToList(); 
var containsExp = Expression.Call(Expression.Constant(myArray), 
            "Contains", null, colExpression.Body); 

if (myArray.Count > 0) 
{ 
    myQuery = myQuery.Where(Expression.Lambda<Func<TSource, bool>> 
             (containsExp, colExpression.Parameters)); 
} 

return myQuery; 

列表比在这种情况下数组更好,因为列表中有Contains功能和Array只有扩展

+0

是!这工作完美。 –