gpt4 book ai didi

c# - LINQ 使用 "like"而不是 "(( NVL(INSTR(x, y), 0) ) = 1)"

转载 作者:行者123 更新时间:2023-11-30 12:38:37 31 4
gpt4 key购买 nike

当使用 .Contains()/.StartsWith()/.EndsWith() 时,生成的 SQL 如下所示:

(( NVL(INSTR(x, y), 0) ) = 1)

有没有办法改用它:

LIKE 'x%' or '%x%' or '%x'

因为这两者在查询的执行计划中存在巨大的成本差异(44 000 对 30)。

最佳答案

当我环顾四周时,我发现了 LIKE operator in LINQ其中有一些很好的例子说明如何做到这一点。我已经测试了下面来自上面链接的那个

这是 adobrzyc 发布的将 Like 与 lambda 一起使用的扩展

    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;
}
}

要使用它,您只需在放置 Contains 函数的位置添加 Like 函数。您可以在下面查看示例

            using (CustomerEntities customerContext = new CustomerEntities())
{
IQueryable<Customer> customer = customerContext.Customer.Like(x => x.psn, "%1%");
}

这将创建一个看起来像这样的 sql 查询。

SELECT 
[Extent1].[psn] AS [psn]
FROM [dbo].[Customer] AS [Extent1]
WHERE [Extent1].[psn] LIKE '%1%'

关于c# - LINQ 使用 "like"而不是 "(( NVL(INSTR(x, y), 0) ) = 1)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50817189/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com