从数据库中读取布尔值?

16

在 C# 中,使用 SqlDataReader 从数据库中读取布尔值的方法是什么?

while (reader.Read())
{
    destPath = reader["destination_path"].ToString();
    destFile = reader["destination_file"].ToString();
    createDir = reader["create_directory"].ToString();
    deleteExisting = Convert.ToBoolean(reader["delete_existing"]);
    skipIFolderDate = reader["skipifolderdate"].ToString();
    useTempFile = reader["useTempFile"].ToString();
    password = reader["password"].ToString();
}
在上面的代码中,delete_existing始终是数据库中的1或0。我在MSDN上读到Convert.ToBoolean()不接受1或0作为有效输入,只接受true或false。有没有另一种方法将DB值转换为布尔值?或者我需要在SqlDataReader之外完成这个操作?
另外,我无法更改DB的值,请不要提出“将DB值从1和0更改为true和false”的答案。
谢谢!
5个回答

41
如果delete_existing的类型是SQL Server中的'bit'类型,你可以这样做:
var i = reader.GetOrdinal("delete_existing"); // Get the field position
deleteExisting = reader.GetBoolean(i);

或者(但如果 delete_existing 可能是 DBNull,它将崩溃)

deleteExisting = (bool)reader["delete_existing"];

或者更好的是,下面的代码可以防止 DBNull ,如果列为 DBNull,它会返回 false

deleteExisting = reader["delete_existing"] as bool? ?? false;

否则如果数据库类型是int

deleteExisting = (reader["delete_existing"] as int? == 1) ? true : false;

或者如果它是一个 varchar

deleteExisting = (reader["delete_existing"] as string == "1") ? true : false;

第三种解决方案:我正在尝试将reader["delete_existing"]转换为可空布尔值(bool?)。这样,如果该字段包含DBNull.Value,则转换失败并返回null。因为我更喜欢得到false,所以我使用了 ?? 运算符,它可以将null转换为任何值(例如:null ?? 45 = 45)。我经常使用这个运算符。 - Larry
第二种解决方案:我正在直接转换为布尔值。如果值不是布尔类型,这将抛出异常。例如,如果它是DBNull.Value。这就是为什么它应该与非空位数据库字段一起使用。只需选择适合您需求的即可^^ 顺便问一下,delete_existing 的数据库类型是什么? - Larry
如果底层数据库类型是位(bit),那么reader["delete_existing"].ToString()将返回"True"或"False"而不是1或0,这让我有些担心。否则,如果它是varchar或int类型,deleteExisting = reader["delete_existing"].ToString() = "1"; 就没问题了。 - Larry
1
这个回答解决了我的问题。感谢你们的帮助! - Mr. Ant
如果 delete_existing 可能为 DBNull,它将会崩溃 - 这给了我一个线索,为什么我的代码没有工作。谢谢。 - Goldfish
显示剩余4条评论

3

转换工作:

myVar = (bool)dataReader["myColumn"];

解释:将dataReader对象中名为"myColumn"的列转换为布尔类型,并将结果赋值给变量myVar。


4
如果返回的值确实是一位(bit),那么这个方法可以正常工作。但如果有人懒惰地将一个整数 1 或 0 选择为返回值,那么类型转换会失败。 - canon

1
如果您在SELECT语句中使用CASE并希望使用GetBoolean,则需要在读取之前将列更改为位(bit)类型,可以使用CAST进行转换。
例如:
SELECT CAST((CASE WHEN [Condition] THEN 1 ELSE 0 END) as bit) FROM Table_Name

然后你可以使用。
reader.GetBoolean(0)

1

这个怎么样?

deleteExisting = (reader["delete_existing"] as int?) == 1;

布尔类型可能是最容易转换的类型。这是“是”、“否”的版本:

deleteExisting = string.Equals(reader["delete_existing"] as string, "Y", StringComparision.OrdinalIgnoreCase);

-1
deleteExisting = reader.GetBoolean(reader["delete_existing"]);

这个语句返回了一个错误。我猜是因为 GetBoolean 函数需要传入一个 Int,而 reader["delete_existing"] 还不是一个 int... - Mr. Ant
尝试强制转换一下?我相信它应该会自动转换为int类型,但你可以尝试显式地执行reader.GetBoolean((int)reader["delete_existing"]); - slandau
很抱歉,在GetBoolean(x)中,x不是要转换为bool的值,而是数据读取器中要读取字段的位置整数。 - Larry
2
GetBoolean需要一个序数=要获取的列的索引。 - jgauffin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接