免责声明:虽然可行,但我强烈建议您不要在查询中使用类型转换,因为这会导致严重的查询性能下降。
事实是
Convert.ToInt(x)
c.ClaimsNumber.Substring(c.ClaimNumber.Length - 6)
,EF核心转换器无法在t-SQL中进行翻译。
RIGHT
函数存在于Sql Server中,而且,您将无法将其与当前版本的EF Core一起使用(我正在编写的最后一个版本是3.1.2)。
获得所需内容的唯一解决方案是创建一个sqlserver用户函数,将其与EF Core映射并在查询中使用它。
> dotnet ef migrations add CreateRightFunction
public partial class CreateRightFunctions : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"
CREATE FUNCTION fn_Right(@input nvarchar(4000), @howMany int)
RETURNS nvarchar(4000)
BEGIN
RETURN RIGHT(@input, @howMany)
END
");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"
DROP FUNCTION fn_Right
");
}
}
然后运行数据库更新:
dotnet ef database update
2) 将函数映射到EF核心上下文
在上下文类[DbFunction(“fn_Right”)]
public static string Right(string input, int howMany)
{
throw new NotImplementedException(); // this code doesn't get executed; the call is passed through to the database function
}
3) 在查询中使用函数
var maxId = Db.Claims.Select(c => MyContext.Right(c.ClaimNumber, 6)).Max(x => Convert.ToInt32(x));
生成的查询:
SELECT MAX(CONVERT(int, [dbo].[fn_Right]([c].[ClaimNumber], 6)))
FROM [Claims] AS [c]
另外,当ClaimNumber的最后6个字符首次包含非数字字符时,这将不再有效。如果索赔编号是由人输入的,迟早会发生这种情况。
您应该为数据库和应用程序编码和设计健壮性,即使您非常确定这6个字符始终代表一个数字。他们不可能永远这么做:)