提问者:小点点

ef core Context.Database.ExecutesQLRaw(sql,param1,param2)引发SqlException


我使用的ef核心版本是:3.0,我写的代码不知何故如下:

SqlParameter table = new SqlParameter("@tableName", tableName);
SqlParameter entryId = new SqlParameter("@entryId", id);
string sql = "delete from @tableName where id = @entryId";
context.Database.ExecuteSqlRaw(sql, table , entryId);

我的sql语句有两个参数,我已经定义并传递了这两个参数,但每次执行它时,我只是得到了下面的异常,请帮忙看一看。谢谢

Microsoft.Data.SqlClient.SQLException(0x80131904):必须声明表变量“@TableName”。在Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception,Boolean breakConnection,Action1wrapCloseInAction)在Microsoft.Data.SqlClient.TdSparser.ThrowExceptionandWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)在Microsoft.Data.SqlClient.TdSparser.TryRun(RunBehavior RunBehavior,SqlCommand cmdHandlerolean isAsync,Int32超时,任务(&;Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior RunBehavior,Boolean returnStream,TaskCompletionSource1完成,Int32超时,task&;任务,布尔值(&S;Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery中的usedCache,Boolean asyncWrite,Boolean inRetry,String方法)(TaskCompletionSource1完成,Boolean sendToPipe,Int32超时,Boolean&;Microsoft.Data.SqlClient.SqlCommand.ExecutenOnQuery()中的usedCache,Boolean asyncWrite,Boolean inRetry,String methodName)。Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecutenOnQuery(RelationalCommandParameterObject参数对象)。Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecutesQLRaw(DatabaseFacade DatabaseFacade,String sql,Object[]参数)


共1个答案

匿名用户

不能参数化表名和列名。在C#术语中,这就像是将类名放在一个字符串中并尝试实例化它:

string className = "Person";
className p = new className; //it doesn't work

您的代码必须更像:

SqlParameter entryId = new SqlParameter("@entryId", id);
string sql = "delete from "+tableName+" where id = @entryId";
context.Database.ExecuteSqlRaw(sql, entryId);

不要授予最终用户更改tableName变量内容的能力

Lutti Coelho提供的额外信息:

为了避免查询中的SQL注入,最好使用ExecutesQlInterpotalated方法。这种方法允许使用字符串插值语法,以防止SQL注入攻击。

context.Database.ExecuteSqlInterpolated("delete from {tableName} where id = {id}");

始终对原始SQL查询使用参数化

在将任何用户提供的值引入原始SQL查询时,必须注意避免SQL注入攻击。除了验证这些值不包含无效字符之外,始终使用参数化,它将值与SQL文本分开发送。

特别是,千万不要将带有未经验证的用户提供的值的串联或插值字符串($“”)传递给FromSqlRaw或ExecutesSQLRAW。FromSqlInterpolated和ExecuteSqlInterpolated方法允许使用字符串插值语法,以防止SQL注入攻击。

您可以在以下链接中查看有关原始SQL查询的更多信息:https://docs.microsoft.com/en-us/ef/core/querying/raw-sql

相关问题