使用Access

时间:2016-09-12 01:19:18

标签: c# ms-access dapper

今天当我使用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表是

And my Product table in the database is

在更改之前'说明'作为'描述'事情很完美。但在我运行代码后更改它(没有更改代码中的任何内容)后,它会删除整个表。我很迷惑。因为实际上有人不小心改变了表名而没有在代码中更新。为什么会出现这个问题?以及如何对此进行有效性检查?

我个人认为,如果该字段不在Access数据库中,它应该返回异常或不执行任何操作

更新

目前,我在检查后通过

进行删除
con.Query<Products>("select ProductNumber, Description from products")

如果正确的字段名称不在必需的表中,则会生成异常。但这不是这个问题的答案。我希望有人给出正确答案

1 个答案:

答案 0 :(得分:1)

我能够重现您的问题,而且似乎与原始字段名称为Description的事实有关,参数声明@Description会导致Dapper创建OleDbParameter.ParameterNameDescription

在第一种情况下,当列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 });