C# linq到sql startwith性能索引列
我首先使用实体代码。 索引列:C# linq到sql startwith性能索引列,c#,sql,linq,entity,C#,Sql,Linq,Entity,我首先使用实体代码。 索引列: SourceCatalogId 残废 类别路径 表中有40000行 我的问题是查询需要40秒 var result = DBContext.Set<SourceProduct>() .Include(x => x.SalesHistories, x => x.SourceCatalog) .Where(p => p.SourceCatalogId == 2)
- SourceCatalogId
- 残废
- 类别路径
var result = DBContext.Set<SourceProduct>()
.Include(x => x.SalesHistories, x => x.SourceCatalog)
.Where(p => p.SourceCatalogId == 2)
.where(p => p.Disabled == false)
.where(x => x.CategoryPath.StartsWith("MyPath"))
.orderby(x => x.ShortDesignation)
.Skip(1)
.Take(10)
.toList();
在where子句之前的最后一个子句中,如果我在中删除“转义N”~”:
查询需要4秒
这正常吗?索引使用?我如何用startWith解决它
编辑
categoryPath的索引属性:
[Index("IX_SourceProduct_SourceCatalogId_Disabled_CategoryPath", 3), StringLength(400)]
public string CategoryPath { get; set; }
EDIT2
好吧,我想我已经很接近了,我认为问题在于存储过程
string search = "julien";
var list = db.Users.Where(x => x.Name.StartsWith(search));
string query = list.ToString();
=>
挑选
[Extent1]。[UserId]作为[UserId],
[Extent1].[Name]作为[Name]
来自[dbo].[Users]作为[Extent1]
其中[Extent1].[Name]像@p_uulinq_u0ESCAPE N'~'
var list2 = db.Users.Where(x => x.Name.StartsWith("julien"));
string query2 = list2.ToString();
=>
挑选
[Extent1]。[UserId]作为[UserId],
[Extent1].[Name]作为[Name]
来自[dbo].[Users]作为[Extent1]
其中[Extent1].[Name]像N'julien%'
所以,如果我在get存储过程的查询中使用变量,如果我使用const,我就得到select
在存储过程(由实体生成)中,使出现@p\u linq\u 0因此添加转义N'~'
避免在变量中使用通配符
所以现在的问题更简单了。如何避免使用变量进行查询?有可能吗?
谢谢,所以您需要在这里获取变量的值,并将其用作正在生成的
表达式
中的常量。这其实是很有可能的。我们需要的是一个表达式,它接受您想要的参数作为实数选择器的参数,接受作为常量值占位符的第二个参数,然后接受您想要成为常量的值。然后,我们可以用常量值替换参数的所有实例,只留下一个将实际参数映射到结果的函数:
public static Expression<Func<TSource, TResult>> EmbedConstant
<TSource, TResult, TConstant>(
this Expression<Func<TSource, TConstant, TResult>> expression,
TConstant constant)
{
var body = expression.Body.Replace(
expression.Parameters[1],
Expression.Constant(constant));
return Expression.Lambda<Func<TSource, TResult>>(
body, expression.Parameters[0]);
}
这允许您映射以下内容:
string search = "julien";
var list = db.Users.Where(x => x.Name.StartsWith(search));
string query = list.ToString();
为此:
string search = "julien";
Expression<Func<User, string, bool>> predicate =
(item, searchTerm) => item.Name.StartsWith(searchTerm);
var list = db.Users.Where(predicate.EmbedConstant(search));
string query = list.ToString();
string search=“julien”;
表达式谓词=
(item,searchTerm)=>item.Name.StartsWith(searchTerm);
var list=db.Users.Where(predicate.EmbedConstant(search));
字符串查询=list.ToString();
只要找到这篇文章,但不知道是否有解决方案?您是使用全文索引,还是仅使用普通索引(这对您的部分字符串匹配没有帮助)?@Mashton我不理解您的问题,但这是我如何使用代码索引第一次看到第一次编辑当您想要加快字符串模式匹配时使用全文索引,这与列的普通索引不同。索引列意味着它可以更快地找到精确的列匹配,但FTI允许您匹配这些字符串的位。您将无法使用linq.StartsWith
,因为FTI要求您使用sql命令CONTAINS
,这意味着您必须开始调用存储过程。但是速度的提高是值得的。我们从1M30转到@Mashon谢谢你的回答。现在,全文索引更清晰了。但我需要的只是特性,简单的索引应该足够了(对于包含特性的特性,您是对的,将需要全文)。当我在sql查询中删除“ESCAPE N”~''时,我可以检查我在说什么。查询速度非常快,我在sql profiler中看到,因此我使用了索引。如何在实体中禁用转义功能?看起来很接近这一点:太棒了,它能工作!!!在这上面花了一天时间。。。非常感谢你。我能给你一只熊吗(就像我们在法国说的谢谢)WTF?所有这些代码只是为了在查询中包含Contains或StartWIth???没有这个。。执行起来会很慢。我如何将它与LINQ to对象一起使用?它给出了错误尝试为linq to object var results=(从db.mytable中的I开始,其中I.mychildtable.col1.contains(搜索)选择I.tolist());知道上面的代码放在哪里会很有帮助。
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
string search = "julien";
var list = db.Users.Where(x => x.Name.StartsWith(search));
string query = list.ToString();
string search = "julien";
Expression<Func<User, string, bool>> predicate =
(item, searchTerm) => item.Name.StartsWith(searchTerm);
var list = db.Users.Where(predicate.EmbedConstant(search));
string query = list.ToString();