今天当我使用Access时,我尝试通过更改Access中的一个表名但不更新代码并尝试观察行为来进行一项测试
例如,我的代码是
Product product = new Product(); //Delete Works well
product.ProductNumber = "P1";
product.Description = "TestProduct1";
var deleteStatement = @"Delete from Product Where Description = @Description";
int outp = con.Execute(deleteStatement, new { Description = product.Description });
我的数据库中的Product表是
在更改之前'说明'作为'描述'事情很完美。但在我运行代码后更改它(没有更改代码中的任何内容)后,它会删除整个表。我很迷惑。因为实际上有人不小心改变了表名而没有在代码中更新。为什么会出现这个问题?以及如何对此进行有效性检查?
我个人认为,如果该字段不在Access数据库中,它应该返回异常或不执行任何操作
更新
目前,我在检查后通过
进行删除con.Query<Products>("select ProductNumber, Description from products")
如果正确的字段名称不在必需的表中,则会生成异常。但这不是这个问题的答案。我希望有人给出正确答案
答案 0 :(得分:1)
我能够重现您的问题,而且似乎与原始字段名称为Description
的事实有关,参数声明@Description
会导致Dapper创建OleDbParameter
其.ParameterName
是Description
。
在第一种情况下,当列Description
实际存在时,Access数据库引擎会识别此
var deleteStatement = @"Delete from Product Where Description = @Description";
// ^^^^^^^^^^^
作为有效的列名,DELETE按预期工作
将列重命名为Descr
后,Access数据库引擎不再将Description
识别为字段名称(因为它不是),因此它将成为另一个参数占位符。 似乎结果是被评估为
Delete from Product Where Description = Description
并且由于参数与其自身的比较Description = Description
始终为TRUE
,因此它实际上与
Delete from Product Where TRUE
并删除所有行。
通过确保我们提供给Dapper的参数名称与字段名称不匹配,可以避免这种情况。例如,以下代码在Description
字段重命名为Descr
后会抛出异常。
var deleteStatement = @"Delete from Product Where Description = @d";
int outp = con.Execute(deleteStatement, new { d = product.Description });