【发布时间】:2026-01-28 13:40:02
【问题描述】:
我的数据库架构默认使用 varchar。使用 EF(6) 代码优先方法,我通过将字符串的 ColumnType 设置为 varchar 来确保我的模型是正确的:modelBuilder.Properties<string>().Configure(p => p.HasColumnType("varchar"));
我正在使用 PredicateBuilder 来构建我的 where 子句,并且一切都按预期工作; LINQ 使用 varchar 数据类型创建参数化查询。我也尝试过不使用 PredicateBuilder:出现完全相同的问题。
但是,一旦我添加了一个 Select 语句,LINQ 突然决定将数据类型更改为 nvarchar,而我想不出任何理由。这当然会对我的查询产生严重的负面影响,因为 sql server 现在必须进行大量隐式转换,从而使我的索引无用。它现在是扫描表而不是搜索。
var ciPredicate = PredicateBuilder.New<InfoEntity>(true);
ciPredicate = ciPredicate.And(x => x.InfoCode == ciCode);
ciPredicate = ciPredicate.And(x => x.Source == source);
//varchar - N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)'
var ciQuery2 = this.Scope.Set<InfoEntity>().Where(ciPredicate).ToList();
//varchar - N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)'
var ciQuery3 = this.Scope.Set<InfoEntity>().Where(ciPredicate).GroupBy(x => new { x.Source, x.InfoKey }).ToList();
//varchar - N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)'
var ciQuery4 = this.Scope.Set<InfoEntity>().Where(ciPredicate).GroupBy(x => new { x.Source, x.InfoKey }).ToList().Select(group => group
.OrderByDescending(x => x.InfoSeqNr)
.FirstOrDefault()
);
//nvarchar - N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)'
var ciQueryNvarchar = this.Scope.Set<InfoEntity>().Where(ciPredicate).GroupBy(x => new { x.Source, x.InfoKey })
.Select(group => group
.OrderByDescending(x => x.InfoSeqNr)
.FirstOrDefault()
).ToList();
表定义:
CREATE TABLE Info(
Id int NOT NULL,
InfoKey int NOT NULL,
Source varchar(50) NOT NULL,
InfoCode varchar(50) NOT NULL,
InfoDesc varchar(4000) NOT NULL,
InfoSeqNr int NOT NULL
)
由于这只是一个查询的开始,我们不能在中间使用 ciQuery4 和 ToList()。
我一生都无法弄清楚为什么会发生这种情况,我们将不胜感激。
【问题讨论】:
标签: c# sql-server linq entity-framework-6