将 SQL 转换为 LINQ 方法表达式
Posted
技术标签:
【中文标题】将 SQL 转换为 LINQ 方法表达式【英文标题】:Convert SQL to LINQ method expression 【发布时间】:2022-01-19 14:13:37 【问题描述】:我在数据库中有场景
CREATE TABLE #MyVersions
(
MyVersion VARCHAR(100) NULL
)
DELETE FROM #MyVersions
INSERT INTO #MyVersions
(MyVersion)
VALUES
(NULL),
(''),
('10001'),
('10001_2'),
('10001_3'),
('10001_4'),
('10001_6'),
('10001_9'),
('10001_11'),
('10001_5'),
('10001_7'),
('10001_8'),
('10001_10'),
('10001_12')
SELECT MyVersion
FROM #MyVersions
Order by CASE MyVersion
WHEN NULL THEN MyVersion
ELSE CAST(SUBSTRING(MyVersion,
charindex('_', MyVersion) + 1,
LEN(MyVersion)-charindex('_', MyVersion)) AS INT)
END
我想将上面的 select 语句转换为 Entity Framework LINQ 方法表达式。
实际上我想按'_'之后的整数部分对表格进行排序
有人可以帮忙吗? 谢谢
【问题讨论】:
你没有。修复不良设计。表字段应该存储 one 值。显然,您希望将这些值视为两个单独的字段并查询第二个字段。 LINQ 不是 SQL 的替代品,它是 ORM 的一种语言。 ORM 可以将对象映射到关系表,并且不能修复不良的数据库设计 你有一个有效的点。根据规范化的基本规则,该字段不是原子的。这是旧数据库,现在我们正在迁移到新系统 此查询无法利用任何涵盖MyVersion
的索引。除非有很多行,否则将数据加载到内存中并在客户端进行拆分和排序会更容易并且可能更快。另一种选择是使用计算列来提取该字符串的不同部分。该列可以很容易地映射到对象属性。它甚至可以被索引以提高性能。这将允许您使用 ORDER BY MajorVersion, MinorVersion
其中 MajorVersion 和 MinorVersion 是计算列
您的积分有效。我正在考虑这样做。结果中几乎没有最多二十行
那么,您要转换什么? OrderBy
或带有临时表的整个语句?
【参考方案1】:
对几行使用 AsEnumerable 是可行的,所以你可以这样做(考虑到没有负值,所以 null 可以被视为 -1):
ctx.MyVersions.Select(mv => mv.My_Version)
.AsEnumerable()
.OrderBy(mv => string.IsNullOrEmpty(mv)
?-1
:int.Parse(mv.Split('_').Last()));
【讨论】:
由于翻译是针对OrderBy
的,我认为行数并不重要,无论如何它们都会返回给客户端,所以除非客户端明显慢于服务器,性能应该相似。但是我不会使用Split
,而是使用IndexOf
(Split
创建一个string[]
你只是在扔掉)。
@NetMage,行数很重要,是否将所有内容都提供给客户端。对于排序,我认为 Split 是一个更好的选择,IndexOf 需要一个复杂的表达式。
Split
会产生大量垃圾而收效甚微。至于行数,因为这是针对OrderBy
,所以无论OrderBy
是在客户端还是服务器上执行,相同的行数都会返回给客户端。
@NetMage,这是错误的。以上是关于将 SQL 转换为 LINQ 方法表达式的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有内连接的 sql 查询转换为 linq lambda 表达式?