您可以使用params
关键字来接受任意数量的参数:
public static IEnumerable<T> MyMethod<T>(this IEnumerable<T> entity,
string param,
params Func<T, string>[] selectors)
{
foreach(var selector in selectors)
{
entity = entity.Where(l =>
SqlFunctions.PatIndex(param, selector(l)) > 0);
}
return entity;
}
但是,我怀疑这将在实体框架中按原样工作。我认为您需要使用Expression<Func<T, string>>
可以转换 SQL 的实体框架:
public static IEnumerable<T> MyMethod<T>(
this IQueryable<T> entity,
string pattern,
params Expression<Func<T, string>>[] selectors)
{
var method = typeof(SqlFunctions).GetMethod("PatIndex");
foreach(var selector in selectors)
{
var param = Expression.Parameter(typeof(T));
var call = Expression.Call(method, Expression.Constant(pattern), selector);
var gt = Expression.GreaterThan(call, Expression.Constant(0));
var filter = Expression.Lamda(call, param);
entity = entity.Where(filter);
}
return entity;
}
然后你可以这样称呼它:
dbContext.ENTITY.MyMethod("%foo",
f => f.SomeProp1,
f => f.SomeProp2,
f => f.SomeProp3).ToList();
要将其与多个pattern
参数一起使用,您可以使用字典(我不会实现方法主体,因为从上面的代码中如何做到这一点应该很明显):
public static IEnumerable<T> MyMethod<T>(
this IEnumerable<T> entity,
Dictionary<string, Func<T, bool>> filters)
{
...
}
你可以这样称呼它:
dbContext.ENTITY.MyMethod(new Dictionary<string, Func<Entity, bool>>()
{
{ "%foo", l => l.Prop1 },
{ "%bar", l => l.Prop2 },
});
或者,您可以使用元组数组:
public static IEnumerable<T> MyMethod<T>(
this IQueryable<T> entity,
string pattern,
params Tuple<string, Func<T, string>>[] filters)
{
...
}
你可以这样称呼它:
dbContext.ENTITY.MyMethod(
Tuple.Create("%foo", (Func<Entity, string>)(l => l.Prop1)),
Tuple.Create("%bar", (Func<Entity, string>)(l => l.Prop2)));
当然,您也可以创建自己的自定义类来包装这些参数,这样您就不必重复指定委托类型。
相同的技术可以很容易地应用于IQueryable
我上面列出的解决方案。