使用StartsWith进行过滤时,EF不使用SQL索引

Xav*_*nas 3 sql-server entity-framework ef-code-first

以下LINQ查询过滤带StartsWith()谓词的行:

db.Pictures.Where(pic => pic.Filename.StartsWith(path)).Count();
Run Code Online (Sandbox Code Playgroud)

其中转换为以下SQL(来自SQL Server Profiler):

exec sp_executesql N'SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[Pictures] AS [Extent1]
    WHERE [Extent1].[Filename] LIKE @p__linq__0 ESCAPE N''~''
)  AS [GroupBy1]',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'10429\2\6\%'
Run Code Online (Sandbox Code Playgroud)

Filename列的类型为VARCHAR(255)并已编制索引.但是,由于N in,查询不使用索引ESCAPE N'~'.

在查询执行计划中,我可以看到一个警告:

表达式中的类型转换(CONVERT_IMPLICIT(NVARCHAR(255),[Extent1].[Filename],0))可能影响查询计划选择中的"CardinalityEstimate"

删除N时,查询运行正常(使用索引).

我该如何解决这个问题?

(一个明显的解决方案可能是将列的类型更改为NVARCHAR,但这似乎并不理想,因为我实际上不需要存储unicode数据)

cka*_*kal 5

您需要将模型设置为varchar.您可以通过覆盖OnModelCreating上下文来配置它.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Picture>().Property(p => p.Filename).IsUnicode(false);
}
Run Code Online (Sandbox Code Playgroud)