EF Core检查指定表索引存在性时查询返回false的问题
EF Core 检查索引存在性异常排查
问题场景
尝试通过EF Core检查指定表中是否存在目标索引,参考方案后编写代码如下:
return context.Database.SqlQuery<int?>($"SELECT 1 as Value FROM sys.indexes WHERE name = '{indexName}' AND object_id = OBJECT_ID('{schema}.{table}') AND is_unique_constraint = 0").SingleOrDefault() != null;
代码生成的SQL语句为:
SELECT 1 as Value FROM sys.indexes WHERE name = 'UK_value_type' AND object_id = OBJECT_ID('utl.value_type') AND is_unique_constraint = 0
但这段代码始终返回false,而直接在SSMS中执行完全相同的SQL语句,却能查到该索引确实存在,查询结果示例:
2050106344 UK_value_type 3 2 NONCLUSTERED 1 1 0 0 0 0 0 0 0 0 1 1 0 NULL NULL 0 0
核心问题分析与解决方法
1. 字符串拼接导致的匹配偏差(含SQL注入风险)
代码中直接拼接indexName、schema、table参数,不仅存在SQL注入风险,还可能因为参数包含特殊字符、大小写差异(若数据库启用区分大小写排序规则)导致匹配失败。
修正方案:使用参数化查询
改用参数化方式传递变量,确保查询匹配准确,同时规避注入风险:
var querySql = @"SELECT 1 as Value FROM sys.indexes WHERE name = @IndexName AND object_id = OBJECT_ID(@SchemaQualifiedTable) AND is_unique_constraint = 0"; var result = context.Database.SqlQuery<int?>(querySql, new SqlParameter("@IndexName", indexName), new SqlParameter("@SchemaQualifiedTable", $"{schema}.{table}")) .SingleOrDefault(); return result != null;
2. is_unique_constraint 过滤条件错误
从SSMS返回的结果来看,需先确认目标索引的is_unique_constraint字段值:如果该索引是通过ALTER TABLE ADD CONSTRAINT创建的唯一约束,对应的is_unique_constraint值为1,此时代码中is_unique_constraint = 0的条件会直接过滤掉该索引。
验证与修正步骤:
- 先在SSMS中执行以下查询确认字段值:
SELECT name, is_unique_constraint FROM sys.indexes WHERE name = 'UK_value_type' AND object_id = OBJECT_ID('utl.value_type') - 根据返回的
is_unique_constraint值调整代码中的过滤条件:若值为1,则去掉AND is_unique_constraint = 0,或改为AND is_unique_constraint = 1。
3. 表对象识别歧义
可在OBJECT_ID函数中明确指定对象类型为用户表,避免数据库误识别其他对象:
OBJECT_ID(N'{schema}.{table}', N'U')
对应的代码参数化版本也可同步调整:
var querySql = @"SELECT 1 as Value FROM sys.indexes WHERE name = @IndexName AND object_id = OBJECT_ID(@SchemaQualifiedTable, N'U') AND is_unique_constraint = 0";
内容的提问来源于stack exchange,提问作者Rok
相关产品推荐
相关产品推荐

