与Column Number rather than Column Name类似,但我认为它有所不同,因为这是针对未命名的列,而我的列名称,我只是提前知道这些名称。
首先,一些背景知识。我正在创建一个方法,将查询及其参数作为参数,然后运行查询(使用Dapper)并检查第一行,第一列值是1还是0.它的目的是作为数据库的通用验证器。
例如,如果某些表中存在某些值,则用户可以输入在唯一行的唯一列中返回1的查询,否则返回0。这种方法的使用是故意非常广泛的,并且大部分工作都放在用户编写查询上(我还应该澄清,"用户"在这种情况下总是另一个开发人员,并且使用是在代码调用此方法,而不是表示输入)。
我想查询我的数据库并获取第一行第一列的值,而不知道列的名称提前。理想情况下(虽然我不确定Dapper调用中是否可行),我也希望要求结果中只有一行和一列。当我在搜索时,我在this帖子的第一个答案基础上找到了我的初始解决方案,但发现为了实现这一点,我需要知道该列的名称:
var dict = connection.Query(query, parameters).ToDictionary(row => (string)row.VALUE);
if(dict.ElementAt(0).Value != 1){
//do stuff
}
我想到的只是添加一个要求,即用户添加一个别名,将第一列命名为常量值(在本例中为VALUE
),但我不想把负担放在我的身上用户,如果可能的话。
最终我的核心问题是:如何在不知道列名的情况下使用Dapper获取DB中命名列的值? 有没有人有任何想法?
答案 0 :(得分:3)
我通过使用int作为通用Query方法中的类型来成功完成此操作:
int value = conn.Query<int>(sql,
commandType: CommandType.StoredProcedure).FirstOrDefault();
注意使用FirstOrDefault方法。所以你得到0或者数据库中的任何值。
答案 1 :(得分:0)
最简单的方法是确保SQL命令ALWAYS通过别名返回相同的列名。然后你的C#代码可以使用该别名。
答案 2 :(得分:0)
使用Tortuga Chain
var filterObject = new {ColumnA = 1, ColumnB = "X", ColumnC = 17};
var result = DataSource.From(tableName, filterObject).ToInt32(columnName).Execute();
我还想要求结果中只有一行和一列
默认情况下,Chain使用DbCommand.ExecuteScalar。这将返回第一行的第一列,忽略其他所有内容。要添加该限制,我会这样做:
{{1}}
另一种选择是更改生成SQL的方式。例如,
{{1}}
这样做的好处是可以免受SQL注入攻击(这可能是您的担忧),并确保您只在SQL执行之前返回一列。