为什么LINQ在EF模式中正确声明时在查询中使用错误的数据类型?

问题描述 投票:4回答:1

我的数据库架构默认使用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
1个回答
1
投票

这似乎是EF中的错误...或者是真的吗?

© www.soinside.com 2019 - 2024. All rights reserved.