我正在尝试基于外部参数(通过搜索表单传递)进行比较,以确定比较类型("%string"
或"string%"
或"%string%"
)
我正朝着以下方向思考:
query = query.Where(
Entity.StringProperty.Like("SearchString", SelectedComparsionType)
)
类似方法会比基于所选类型返回
.StartsWith()
或.EndsWith()
或.SubString()
我对表达式的了解显然远非如此,因为我无法构造一个可以产生正确结果的方法(SQL中的服务器端比较与StartsWith
方法一样)。
答案 0 :(得分:17)
简单方法
只需使用
if (comparison == ComparisonType.StartsWith)
query = query.Where(e => e.StringProperty.StartsWith("SearchString"));
else if ...
艰难的方式
如果你想做这样的事情,要么确保你的LINQ提供程序能以某种方式被告知这个新方法,以及它如何转换为SQL(不太可能),或者阻止你的方法到达LINQ提供者,并提供提供者理解的东西(很难)。例如,而不是
query.Where(e => CompMethod(e.StringProperty, "SearchString", comparsionType))
你可以创建像
这样的东西var query = source.WhereLike(e => e.StringProperty, "SearchString", comparsionType)
使用以下代码
public enum ComparisonType { StartsWith, EndsWith, Contains }
public static class QueryableExtensions
{
public static IQueryable<T> WhereLike<T>(
this IQueryable<T> source,
Expression<Func<T, string>> field,
string value,
SelectedComparisonType comparisonType)
{
ParameterExpression p = field.Parameters[0];
return source.Where(
Expression.Lambda<Func<T, bool>>(
Expression.Call(
field.Body,
comparisonType.ToString(),
null,
Expression.Constant(value)),
p));
}
}
您甚至可以通过这种方式添加其他标准
var query = from e in source.WhereLike(
e => e.StringProperty, "SearchString", comparsionType)
where e.OtherProperty == 123
orderby e.StringProperty
select e;
非常非常困难的方式
在技术上可以在提供者看到之前重写表达式树,因此可以首先使用您想到的查询,但是您必须< / p>
Where(this IQueryable<EntityType> source, Expression<Func<EntityType, bool>> predicate)
以拦截Queryable.Where
,CompMethod
方法重写表达式树,将String
替换为Queryable.Where
,但对于你的想法,这可能太复杂了。
答案 1 :(得分:1)
听起来你应该想要使用:
query = query.Where(
Entity.StringProperty.Contains("SearchString")
)
这应该映射到:
WHERE StringProperty LIKE '%SearchString%'
这也应该适用于更高级的搜索掩码,例如“Mr?Sm%th”,但我还没有像我一样测试任何搜索字符串。
更新:基于OP编辑
听起来你要求的是以下内容:
public enum SelectedComparsionType
{
StartsWith,
EndsWith,
Contains
}
public static bool Like(this string searchString, string searchPattern, SelectedComparsionType searchType)
{
switch (searchType)
{
case SelectedComparsionType.StartsWith:
return searchString.StartsWith(searchPattern);
case SelectedComparsionType.EndsWith:
return searchString.EndsWith(searchPattern);
case SelectedComparsionType.Contains:
default:
return searchString.Contains(searchPattern);
}
}
这将允许您根据需要编写代码,即:
query = query.Where(
Entity.StringProperty.Like("SearchString", SelectedComparsionType.StartsWith)
)
但是, 个人 ,我会直接调用所需的字符串函数来替换SelectedComparsionType的任何使用。即
query = query.Where(
Entity.StringProperty.StartsWith("SearchString")
)
因为它仍然会映射到SQL'LIKE'查询。
答案 2 :(得分:0)
这正是我的想法,谢谢。我已经编写了类似的东西,但它没有转换为SQL。例如,如果我直接这样做,它就起作用了:
Entity.StringProperty.EndsWith("SearchString");
如果我使用专用方法,它无效:
CompMethod("BaseString","SearchString",SelectedComparsionType.EndsWith)
我认为它可能与表达式评估有关,我只是不确定是什么。
答案 3 :(得分:-1)
最好使用Regex来解决此问题。