【发布时间】:2017-04-11 08:32:24
【问题描述】:
我正在尝试为具有以下签名的 ServiceStack.OrmLite.SqlExpressionVisitor 编写通用通配符搜索:
public static SqlExpressionVisitor<T> WhereWildcardSearch<T> (this SqlExpressionVisitor<T> ev, Expression<Func<T,string>> field, string search)
其中 ev 是过滤器的其余部分,field 是要搜索的字段的 getter,search 是输入的词。
通常(非通用)我会写以下内容:
if(search.StartsWith('*') && search.EndsWith('*'))
ev = ev.Where(x => x.foo.Contains(search.Trim('*')));
当然还有 x.foo.StartsWith 或 EndsWith 的变体。
现在我正在搜索类似(伪代码:)
ev = ev.Where(x => field(x).Contains(search.Trim('*')));
当然我不能直接编译和调用表达式,因为这应该使用Linq2Sql翻译成Sql。
这是我目前的代码:
var getFieldExpression = Expression.Invoke (field, Expression.Parameter (typeof (T), "getFieldParam"));
var searchConstant = Expression.Constant (search.Trim('*'));
var inExp = Expression.Call (getFieldExpression, typeof(String).GetMethod("Contains"), searchConstant);
var param = Expression.Parameter (typeof (T), "object");
var exp = Expression.Lambda<Func<T, bool>> (inExp, param);
ev = ev.Where (exp);
请不要告诉我我应该直接使用$"LIKE %search%" 或其他方式编写 SQL - 我知道还有其他方法,但是解决这个问题将有助于我对 Linq 和表达式的总体理解,并且当我可以的时候它会困扰我解决不了。
【问题讨论】:
标签: c# linq linq-to-sql servicestack ormlite-servicestack