SQL 查询 CAST 到 int + 1 到 LINQ
TSQL query CAST to int + 1 to LINQ
我正在为以下 linq to sql 查询绞尽脑汁。想法是获得与所有 REG_CODE 项相比最小的下一个整数。该字段 (REG_CODE) 是一个 varchar(10) 字段。
我正在尝试将以下 tsql 转换为 linq-to-entities (EF 6.0):
SELECT TOP 1 CAST( [Extent1].[REG_CODE] AS int) + 1
FROM [dbo].[Notifications] [Extent1]
WHERE NOT ([Extent1].[REG_CODE] LIKE N'%~[a-z]%' ESCAPE N'~') AND (1 = (ISNUMERIC([Extent1].[REG_CODE]))) AND
NOT EXISTS(SELECT * FROM [dbo].[Notifications] t2 WHERE CAST( t2.REG_CODE AS int) = CAST( [Extent1].[REG_CODE] AS int) + 1 )
ORDER BY [Extent1].[REG_CODE]
(注意+1,我要下一部分)
设计并不是那么棒。字段 [REG_CODE] 应该是一个整数字段,但它不是,也不会很快成为整数字段。
这个:
float notificationMaxRegCodeNumeric =
db.Notifications.Where(not => not.Reg_Code != null && !not.Reg_Code.Contains("[a-z]") && SqlFunctions.IsNumeric(not.Reg_Code) == 1)
.OrderByDescending(not => not.Reg_Code)
.Select(not => not.Reg_Code)
.Cast<int>()
.Max();
成功转换为:
SELECT MAX(CAST( [Extent1].[REG_CODE] AS int)) AS[A1]
FROM[dbo].[Notifications] AS[Extent1]
WHERE ([Extent1].[REG_CODE] IS NOT NULL) AND(NOT([Extent1].[REG_CODE] LIKE N'%~[a-z]%' ESCAPE N'~')) AND(1 = (ISNUMERIC([Extent1].[REG_CODE])))
到目前为止我有:
int nextNotificationMaxRegCodeNumericInt = db.Notifications.Where(not =>
not.Reg_Code != null && !not.Reg_Code.Contains("[a-z]") &&
SqlFunctions.IsNumeric(not.Reg_Code) == 1 &&
db.Notifications.Any(klainternal => not.Reg_Code.Cast<int>() == klainternal.Reg_Code.Cast<int>())
)
.OrderByDescending(not => not.Reg_Code)
.Select(not => not.Reg_Code)
.Cast<int>();
但它抛出:
DbExpressionBinding requires an input expression with a collection ResultType`.
还有 Convert.ToInt32()
正在投掷:
linq to entities does not recognize the method 'int32 toint32(system.string)' method`
(.Max()
与我正在寻找的内容并不相关,但它在查询的工作部分)
有什么建议吗?
首先,恭喜你找到了Cast<T>()
绝招!这似乎是将 string
转换为其他东西的唯一开箱即用的 EF6 方式 - 所有其他尝试,如 (int)(object)stringValue
或 Convert.ToInt32(stringValue)
都被简单地阻止,因为不受支持。
但注意Cast<T>()
方法是为IEnumerable
和IQueryable
定义的,结果分别是IEnumerable<T>
和IQueryable<T>
,即按顺序工作并产生序列。它出现在 string
上,因为 string
是 IEnumerable<char>
,因此 IEnumerable
,但这不是我们需要的。
所以诀窍是始终使用投影 (Select
) + Cast
进行转换。将它应用于您的查询会导致类似这样的结果:
int nextNotificationMaxRegCodeNumericInt = db.Notifications
.Where(n => n.Reg_Code != null &&
!n.Reg_Code.Contains("[a-z]") &&
SqlFunctions.IsNumeric(n.Reg_Code) == 1)
.Select(n => n.Reg_Code).Cast<int>() // <--
.Select(reg_Code => reg_Code + 1)
.Where(reg_Code => !db.Notifications.Select(n => n.Reg_Code).Cast<int>() // <--
.Contains(reg_Code))
.OrderByDescending(reg_Code => reg_Code)
.FirstOrDefault();
转换为
SELECT TOP (1)
[Project1].[C1] AS [C1]
FROM ( SELECT
CAST( [Extent1].[Reg_Code] AS int) + 1 AS [C1]
FROM [dbo].[Notifications] AS [Extent1]
WHERE ([Extent1].[Reg_Code] IS NOT NULL) AND ( NOT ([Extent1].[Reg_Code] LIKE N'%~[a-z]%' ESCAPE N'~')) AND (1 = (ISNUMERIC([Extent1].[Reg_Code])))
) AS [Project1]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Notifications] AS [Extent2]
WHERE CAST( [Extent2].[Reg_Code] AS int) = [Project1].[C1]
)
ORDER BY [Project1].[C1] DESC
我正在为以下 linq to sql 查询绞尽脑汁。想法是获得与所有 REG_CODE 项相比最小的下一个整数。该字段 (REG_CODE) 是一个 varchar(10) 字段。 我正在尝试将以下 tsql 转换为 linq-to-entities (EF 6.0):
SELECT TOP 1 CAST( [Extent1].[REG_CODE] AS int) + 1
FROM [dbo].[Notifications] [Extent1]
WHERE NOT ([Extent1].[REG_CODE] LIKE N'%~[a-z]%' ESCAPE N'~') AND (1 = (ISNUMERIC([Extent1].[REG_CODE]))) AND
NOT EXISTS(SELECT * FROM [dbo].[Notifications] t2 WHERE CAST( t2.REG_CODE AS int) = CAST( [Extent1].[REG_CODE] AS int) + 1 )
ORDER BY [Extent1].[REG_CODE]
(注意+1,我要下一部分) 设计并不是那么棒。字段 [REG_CODE] 应该是一个整数字段,但它不是,也不会很快成为整数字段。
这个:
float notificationMaxRegCodeNumeric =
db.Notifications.Where(not => not.Reg_Code != null && !not.Reg_Code.Contains("[a-z]") && SqlFunctions.IsNumeric(not.Reg_Code) == 1)
.OrderByDescending(not => not.Reg_Code)
.Select(not => not.Reg_Code)
.Cast<int>()
.Max();
成功转换为:
SELECT MAX(CAST( [Extent1].[REG_CODE] AS int)) AS[A1]
FROM[dbo].[Notifications] AS[Extent1]
WHERE ([Extent1].[REG_CODE] IS NOT NULL) AND(NOT([Extent1].[REG_CODE] LIKE N'%~[a-z]%' ESCAPE N'~')) AND(1 = (ISNUMERIC([Extent1].[REG_CODE])))
到目前为止我有:
int nextNotificationMaxRegCodeNumericInt = db.Notifications.Where(not =>
not.Reg_Code != null && !not.Reg_Code.Contains("[a-z]") &&
SqlFunctions.IsNumeric(not.Reg_Code) == 1 &&
db.Notifications.Any(klainternal => not.Reg_Code.Cast<int>() == klainternal.Reg_Code.Cast<int>())
)
.OrderByDescending(not => not.Reg_Code)
.Select(not => not.Reg_Code)
.Cast<int>();
但它抛出:
DbExpressionBinding requires an input expression with a collection ResultType`.
还有 Convert.ToInt32()
正在投掷:
linq to entities does not recognize the method 'int32 toint32(system.string)' method`
(.Max()
与我正在寻找的内容并不相关,但它在查询的工作部分)
有什么建议吗?
首先,恭喜你找到了Cast<T>()
绝招!这似乎是将 string
转换为其他东西的唯一开箱即用的 EF6 方式 - 所有其他尝试,如 (int)(object)stringValue
或 Convert.ToInt32(stringValue)
都被简单地阻止,因为不受支持。
但注意Cast<T>()
方法是为IEnumerable
和IQueryable
定义的,结果分别是IEnumerable<T>
和IQueryable<T>
,即按顺序工作并产生序列。它出现在 string
上,因为 string
是 IEnumerable<char>
,因此 IEnumerable
,但这不是我们需要的。
所以诀窍是始终使用投影 (Select
) + Cast
进行转换。将它应用于您的查询会导致类似这样的结果:
int nextNotificationMaxRegCodeNumericInt = db.Notifications
.Where(n => n.Reg_Code != null &&
!n.Reg_Code.Contains("[a-z]") &&
SqlFunctions.IsNumeric(n.Reg_Code) == 1)
.Select(n => n.Reg_Code).Cast<int>() // <--
.Select(reg_Code => reg_Code + 1)
.Where(reg_Code => !db.Notifications.Select(n => n.Reg_Code).Cast<int>() // <--
.Contains(reg_Code))
.OrderByDescending(reg_Code => reg_Code)
.FirstOrDefault();
转换为
SELECT TOP (1)
[Project1].[C1] AS [C1]
FROM ( SELECT
CAST( [Extent1].[Reg_Code] AS int) + 1 AS [C1]
FROM [dbo].[Notifications] AS [Extent1]
WHERE ([Extent1].[Reg_Code] IS NOT NULL) AND ( NOT ([Extent1].[Reg_Code] LIKE N'%~[a-z]%' ESCAPE N'~')) AND (1 = (ISNUMERIC([Extent1].[Reg_Code])))
) AS [Project1]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Notifications] AS [Extent2]
WHERE CAST( [Extent2].[Reg_Code] AS int) = [Project1].[C1]
)
ORDER BY [Project1].[C1] DESC