SQL 中的字符串比较
在 SQL 中,字符串可以直接使用 >= 和 <= 进行字典序比较:
SELECT TOP (1000000000) [t21].[nm], [t21].[bh]
FROM [dbo].[XX] AS [t21]
WHERE ([t21].[bh] >= 'FA32014001') AND ([t21].[bh] <= 'FA32016000')Code language: PHP (php)
LINQ 中的问题
LINQ to SQL 不支持对字符串直接使用 >= / <= 运算符:
// 编译报错:运算符 ">=" 无法应用于 "string" 和 "string"
where s.name >= "abc" && s.name <= "xyz"Code language: JavaScript (javascript)
解决方案:使用 CompareTo
string.CompareTo() 返回 int:
- 返回 负数:当前字符串小于参数
- 返回 0:相等
- 返回 正数:当前字符串大于参数
// 相等比较 → 用 Equals
var q = from s in db.Student
where s.name.Equals("abc")
select s;
// 范围比较 → 用 CompareTo
var q2 = from s in db.Student
where s.name.CompareTo("abc") >= 0
&& s.name.CompareTo("xyz") <= 0
select s;Code language: JavaScript (javascript)
生成的 SQL
Equals → =:
SELECT [t0].[id], [t0].[name], [t0].[age], [t0].[birthday], [t0].[nation], [t0].[classname]
FROM [dbo].[Student] AS [t0]
WHERE [t0].[name] = 'abc'Code language: PHP (php)
CompareTo → >= / <=:
SELECT [t0].[id], [t0].[name], [t0].[age], [t0].[birthday], [t0].[nation], [t0].[classname]
FROM [dbo].[Student] AS [t0]
WHERE ([t0].[name] >= 'abc') AND ([t0].[name] <= 'xyz')Code language: PHP (php)
CompareTo被翻译为 SQL 的>=/<=字符串比较,在数据库端按字典序执行。
方法语法写法
// 相等
var r = db.Student
.Where(s => s.name.Equals("abc"))
.ToList();
// 范围
var r2 = db.Student
.Where(s => s.name.CompareTo("abc") >= 0 && s.name.CompareTo("xyz") <= 0)
.ToList();Code language: JavaScript (javascript)
关键要点
| 场景 | LINQ 写法 | 生成 SQL |
|---|---|---|
| 相等 | s.name.Equals("abc") | name = 'abc' |
| 大于 | s.name.CompareTo("abc") > 0 | name > 'abc' |
| 大于等于 | s.name.CompareTo("abc") >= 0 | name >= 'abc' |
| 小于 | s.name.CompareTo("abc") < 0 | name < 'abc' |
| 范围 | CompareTo("a") >= 0 && CompareTo("z") <= 0 | name >= 'a' AND name <= 'z' |
注意: 字符串比较遵循数据库的排序规则(Collation),区分大小写与否取决于数据库设置,与 C# 的
string.Compare默认行为可能不同。
Previous: 查看 LINQ 生成的 SQL 脚本
Next: 同一张表对应多个 DBML 类