有没有办法比较C#LINQ表达式中类似于SQL LIKE运算符的字符串?
假设我有一个字符串列表.在此列表中,我想搜索一个字符串.在SQL中,我可以写:
SELECT * FROM DischargePort WHERE PortName LIKE '%BALTIMORE%'
Run Code Online (Sandbox Code Playgroud)
而不是上述,查询需要linq语法.
using System.Text.RegularExpressions;
…
var regex = new Regex(sDischargePort, RegexOptions.IgnoreCase);
var sPortCode = Database.DischargePorts
.Where(p => regex.IsMatch(p.PortName))
.Single().PortCode;
Run Code Online (Sandbox Code Playgroud)
我上面的LINQ语法不起作用.我有什么问题?
Jon*_*eet 131
通常你使用String.StartsWith/ EndsWith/ Contains.例如:
var portCode = Database.DischargePorts
.Where(p => p.PortName.Contains("BALTIMORE"))
.Single()
.PortCode;
Run Code Online (Sandbox Code Playgroud)
我不知道是否有办法通过LINQ to SQL做正确的正则表达式.(请注意,它确实取决于您正在使用的提供程序 - 它在LINQ to Objects中会很好;这是提供程序是否可以将调用转换为其本机查询格式,例如SQL.)
编辑:正如BitKFu所说,Single当你期望一个结果时应该使用- 当它出现错误时就不会出现这种情况.的选项SingleOrDefault,FirstOrDefault或First应视使用究竟要的是什么.
Mar*_*ell 30
正则表达式?没有.但对于该查询,您可以使用:
string filter = "BALTIMORE";
(blah) .Where(row => row.PortName.Contains(filter)) (blah)
Run Code Online (Sandbox Code Playgroud)
如果你真的想要SQL LIKE,你可以使用System.Data.Linq.SqlClient.SqlMethods.Like(...)哪些LINQ-to-SQL映射到LIKESQL Server.
ado*_*zyc 10
嗯...有时候使用它可能会让人感到不舒服Contains,StartsWith或者EndsWith特别是在搜索值时确定LIKE法定值,例如从开发者那里传递'value%'需要使用StartsWith表达式中的函数.所以我决定为IQueryable对象编写扩展.
用法
// numbers: 11-000-00, 00-111-00, 00-000-11
var data1 = parts.Like(p => p.Number, "%11%");
// result: 11-000-00, 00-111-00, 00-000-11
var data2 = parts.Like(p => p.Number, "11%");
// result: 11-000-00
var data3 = parts.Like(p => p.Number, "%11");
// result: 00-000-11
Run Code Online (Sandbox Code Playgroud)
码
public static class LinqEx
{
private static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains");
private static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
private static readonly MethodInfo EndsWithMethod = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
public static Expression<Func<TSource, bool>> LikeExpression<TSource, TMember>(Expression<Func<TSource, TMember>> property, string value)
{
var param = Expression.Parameter(typeof(TSource), "t");
var propertyInfo = GetPropertyInfo(property);
var member = Expression.Property(param, propertyInfo.Name);
var startWith = value.StartsWith("%");
var endsWith = value.EndsWith("%");
if (startWith)
value = value.Remove(0, 1);
if (endsWith)
value = value.Remove(value.Length - 1, 1);
var constant = Expression.Constant(value);
Expression exp;
if (endsWith && startWith)
{
exp = Expression.Call(member, ContainsMethod, constant);
}
else if (startWith)
{
exp = Expression.Call(member, EndsWithMethod, constant);
}
else if (endsWith)
{
exp = Expression.Call(member, StartsWithMethod, constant);
}
else
{
exp = Expression.Equal(member, constant);
}
return Expression.Lambda<Func<TSource, bool>>(exp, param);
}
public static IQueryable<TSource> Like<TSource, TMember>(this IQueryable<TSource> source, Expression<Func<TSource, TMember>> parameter, string value)
{
return source.Where(LikeExpression(parameter, value));
}
private static PropertyInfo GetPropertyInfo(Expression expression)
{
var lambda = expression as LambdaExpression;
if (lambda == null)
throw new ArgumentNullException("expression");
MemberExpression memberExpr = null;
switch (lambda.Body.NodeType)
{
case ExpressionType.Convert:
memberExpr = ((UnaryExpression)lambda.Body).Operand as MemberExpression;
break;
case ExpressionType.MemberAccess:
memberExpr = lambda.Body as MemberExpression;
break;
}
if (memberExpr == null)
throw new InvalidOperationException("Specified expression is invalid. Unable to determine property info from expression.");
var output = memberExpr.Member as PropertyInfo;
if (output == null)
throw new InvalidOperationException("Specified expression is invalid. Unable to determine property info from expression.");
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
正如Jon Skeet和Marc Gravell已经提到的,你可以简单地采取一个包含条件.但是在你喜欢查询的情况下,采用Single()语句是非常危险的,因为这意味着你只能找到1个结果.如果有更多结果,你会收到一个很好的例外:)
所以我更喜欢使用FirstOrDefault()而不是Single():
var first = Database.DischargePorts.FirstOrDefault(p => p.PortName.Contains("BALTIMORE"));
var portcode = first != null ? first.PortCode : string.Empty;
Run Code Online (Sandbox Code Playgroud)
在本机LINQ中,您可以使用Contains/StartsWith/EndsWith或RegExp的组合.
在LINQ2SQL中使用方法 SqlMethods.Like()
from i in db.myTable
where SqlMethods.Like(i.field, "tra%ata")
select i
Run Code Online (Sandbox Code Playgroud)
添加程序集:System.Data.Linq(在System.Data.Linq.dll中)以使用此功能.
| 归档时间: |
|
| 查看次数: |
221410 次 |
| 最近记录: |