6

我对 ado.net 实体框架中的实体的 linq 有一些问题。基本上我正在做的是这样的:

var results = (from c in companies
    where c.Name.StartsWith(letter)
    select c);

这会被翻译成 SQL,如下所示:

WHERE (CAST(CHARINDEX(@p, [Extent1].[Name]) AS int)) = 1

这很好,但我的表有数百万条记录,所以运行速度非常慢。我需要它来生成是这样的:

WHERE Name LIKE @p + '%'

我搜索了高低,找不到任何解决方案,除了使用存储过程或使用实体 sql ...

有没有办法通过linq做到这一点?可能通过某种方式将 linq 扩展到实体 linq 提供程序,或者以某种方式拦截命令树或生成的查询?

4

6 回答 6

3

我不是 SQL 专家,但猜测这两种语法:

WHERE (CAST(CHARINDEX(@p, [Extent1].[Name]) AS int)) = 1

WHERE Name LIKE @p + '%'

将导致表扫描或理想情况下的索引扫描。最重要的是,他们将执行相同的操作。我通过查看下面的执行计划验证了这一点。最重要的是,您需要重新考虑您的数据库架构或您执行搜索的方式。这不是 LINQ 问题。

一个可能需要改进的领域:确保您已为正在搜索的列编制索引。

替代文字 http://download.binaryocean.com/plan1.gif

替代文字 http://download.binaryocean.com/plan2.gif

于 2009-02-24T14:59:16.460 回答
2

哇,这真是一种奇怪的做法!请注意,LINQ-to-SQL(在这种情况下)使用LIKE @p0 + '%'......非常奇怪。

您使用的是哪个 EF 提供程序(数据库)?SQL 服务器?

正如你所说,存储过程将完成这项工作,但你不应该这样做......非常非常奇怪......

于 2009-02-23T07:46:22.920 回答
1

这是 Linq to Entities 的一个已知问题。与 LIKE 不同,显然这个结构不使用索引。

我们在使用 Substring(转换为 SUBSTRING)方面取得了一些成功。执行计划类似,但在我们的例子中查询执行得更快。

这是另一个“我确定它将在 EF 2 中修复”... :-(

于 2009-04-30T09:37:20.437 回答
0

我尝试改用这种语法

Name.Substring(0, 1) == "E"

生成此 SQL

WHERE N'E' = (SUBSTRING([Name], 0 + 1, 1))

也许这更有效?

于 2009-02-25T22:03:31.097 回答
0

“字母”是字符吗?如果你把它变成一个字符串,会发生什么?

var results = (from c in companies
    where c.Name.StartsWith(letter.ToString())
    select c);
于 2009-02-25T00:08:44.300 回答
0

您可以很容易地在 Link to Entity 中使用真实的like

以下是使其工作所需的:

添加

    <Function Name="String_Like" ReturnType="Edm.Boolean">
      <Parameter Name="searchingIn" Type="Edm.String" />
      <Parameter Name="lookingFor" Type="Edm.String" />
      <DefiningExpression>
        searchingIn LIKE lookingFor
      </DefiningExpression>
    </Function>

到此标签中的 EDMX:

edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/Schema

还要记住<schema namespace="" />属性中的命名空间

然后在上面的命名空间中添加一个扩展类:

public static class Extensions
{
    [EdmFunction("DocTrails3.Net.Database.Models", "String_Like")]
    public static Boolean Like(this String searchingIn, String lookingFor)
    {
        throw new Exception("Not implemented");
    }
}

此扩展方法现在将映射到 EDMX 函数。

更多信息在这里:http: //jendaperl.blogspot.be/2011/02/like-in-linq-to-entities.html

于 2015-07-24T09:04:04.917 回答