问题描述
我有一条从sql Server返回的行和一个整数列值,该值在C#中无法正确转换为布尔值。
我想将整数1转换为布尔值true。但这并没有做到。它将1转换为false或认为它为0并转换为false。
blogPublishedByBlogId.Likedisabled = Convert.ToBoolean(getblogPublishedByBlogIdReader["Likedisabled"]);
这是存储过程通过SSMS返回的行:
Likedisabled
列是一个整数,值= 1,但是在C#中将其转换为值0。为什么?像这样的简单事情应该起作用。这没有道理。
我放入两行“测试代码”以查看整数值。它由存储过程以整数值= 1返回,但是在转换函数Convert.ToInt32之后,我得到了0。请参见下文。
这是几行后的完全填充的模型。当Likedisabled
应该为true时,布尔值都为false。
这是存储过程。它从数据库表中获取所需的数据,并根据Likedisabled
(当前为'L')来设置disLikedisabled
和@LikeOrdislikeIndicator = 'L'
。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GetBlogPublishedByBlogId]
@a_UserName varchar(250) = NULL,@a_IpAddress varchar(250) = NULL,@a_BlogId int = NULL,@a_UserId int = NULL
AS
BEGIN
DECLARE @RowCount int,@ReturnCode int,@CurrentDateTime datetime,@Count int,@UserType varchar(25) = '',@LikeOrdislikeIndicator char(1) = '',-- 'L' for like,'D' for dislike.
@BlogId int = 0,@BlogTitle varchar(250) = '',@BlogContent varchar(max) = '',@LikeCount int = 0,@disLikeCount int = 0,@ModifiedDateTime datetime = NULL,@CreatedDateTime datetime = NULL,@Likedisabled int = 0,@disLikedisabled int = 0,@Message varchar(max),@ApiMessageOut varchar(max),@ApiAccessSwitchOut bit
SELECT @CurrentDateTime = GETDATE()
DECLARE @ErrorLine AS INT;
DECLARE @ErrorMessage AS VARCHAR(2048);
DECLARE @ErrorNumber AS INT;
DECLARE @ErrorSeverity AS INT;
DECLARE @ErrorState AS INT;
DECLARE @DatabaseName AS VARCHAR(255);
DECLARE @ServerName AS VARCHAR(255);
DECLARE @ErrorDescription AS VARCHAR(MAX);
DECLARE @CRLF AS VARCHAR(2);
BEGIN TRY
SET NOCOUNT ON;
IF ( ( @a_UserName = '' OR @a_UserName IS NULL ) OR ( @a_IpAddress = '' OR @a_IpAddress IS NULL )
OR ( @a_BlogId IS NULL ) OR ( @a_UserId IS NULL ) )
BEGIN
SELECT @Message = 'Warning - invalid parameters. They cannot be null or empty.'
IF ( @a_UserName = '' OR @a_UserName IS NULL )
BEGIN
SET @a_UserName = 'No "user name" parameter provided.'
END
IF ( @a_IpAddress = '' OR @a_IpAddress IS NULL )
BEGIN
SET @a_IpAddress = 'No "ip address" parameter provided.'
END
RAISERROR (@Message,16,1)
END
ELSE
BEGIN
-- Do the API security check. If this user is valid,you can continue with further processing.
SELECT @ReturnCode = -1
EXECUTE @ReturnCode = dbo.GetApiAccess
@CurrentDateTime,@a_UserName,@a_IpAddress,@a_ApiAccessSwitchFromGet = @ApiAccessSwitchOut OUTPUT,@a_ApiMessageFromGet = @ApiMessageOut OUTPUT
IF @ReturnCode = -1
BEGIN
RAISERROR ('Critical Error - procedure GetBlogPublishedByBlogId Failed during execute of procedure GetApiAccess',1 )
END
-- Web api access was granted.
IF @ApiAccessSwitchOut = 1
BEGIN
SELECT @BlogId = Blogid,@BlogTitle = BlogTitle,@BlogContent = BlogContent,@LikeCount = LikeCount,@disLikeCount = disLikeCount,@ModifiedDateTime = ModifiedDateTime,@CreatedDateTime = CreatedDateTime
FROM dbo.Blog
WHERE ( BlogId = @a_BlogId AND ActiveSwitch = 1 )
SELECT @ReturnCode = @@ERROR,@RowCount = @@ROWCOUNT
IF @ReturnCode <> 0
BEGIN
SELECT @Message = 'Critical Error - procedure GetBlogPublishedByBlogId during the 1st select.'
RAISERROR (@Message,1)
END
IF @RowCount = 0
BEGIN
SELECT 2 as Status,0 as Blogid,'' as BlogTitle,'' as BlogContent,0 as LikeCount,0 as disLikeCount,NULL as ModifiedDateTime,NULL as CreatedDateTime,@Likedisabled as Likedisabled,@disLikedisabled as disLikedisabled
END
ELSE
BEGIN
SELECT @LikeOrdislikeIndicator = LikeOrdislikeIndicator
FROM dbo.[UserBlogPreference]
WHERE ( BlogId = @a_BlogId AND UserId = @a_UserId )
SELECT @ReturnCode = @@ERROR,@RowCount = @@ROWCOUNT
IF @ReturnCode <> 0
BEGIN
SELECT @Message = 'Critical Error - procedure GetBlogPublishedByBlogId during the 2nd select.'
RAISERROR (@Message,1)
END
IF ( @RowCount = 0 )
BEGIN
SELECT @Likedisabled = 0,@disLikedisabled = 0
END
ELSE
BEGIN
IF @LikeOrdislikeIndicator = 'L'
BEGIN
SELECT @Likedisabled = 1,@disLikedisabled = 0
END
ELSE
BEGIN
SELECT @Likedisabled = 0,@disLikedisabled = 1
END
END
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Return data.
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SELECT 1 as Status,@Blogid as Blogid,@BlogTitle as BlogTitle,@BlogContent as BlogContent,@LikeCount as LikeCount,@disLikeCount as disLikeCount,@ModifiedDateTime as ModifiedDateTime,@CreatedDateTime as CreatedDateTime,@disLikedisabled as disLikedisabled
END
END
ELSE
BEGIN
RAISERROR (@ApiMessageOut,1 )
END
END
RETURN 0
END TRY
BEGIN CATCH
---- code not shown.
END CATCH
END
这是UserBlogPreference表,该表具有用于确定Likedisabled和disLikedisabled设置的指示器。设置为“ L”。
这是模型类:
using System;
using System.ComponentModel.DataAnnotations;
namespace GbngWebApi2.Models
{
public class BlogPublishedByBlogId
{
public int BlogId { get; set; }
public string BlogTitle { get; set; }
public string BlogContent { get; set; }
public int LikeCount { get; set; }
public int disLikeCount { get; set; }
public DateTime ModifiedDateTime { get; set; }
public DateTime CreatedDateTime { get; set; }
public bool Likedisabled { get; set; }
public bool disLikedisabled { get; set; }
}
}
这是对存储过程的调用,是上面的屏幕截图:
public BlogPublishedByBlogIdResults GetBlogPublishedByBlogId(string userName,string ipAddress,int blogId,int userId)
{
BlogPublishedByBlogIdResults blogPublishedByBlogIdResults = new BlogPublishedByBlogIdResults();
sqlDataReader getblogPublishedByBlogIdReader = null;
try
{
dbFunc.OpenDB();
sqlCommand cmd = new sqlCommand("dbo.GetBlogPublishedByBlogId",dbFunc.objConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@a_UserName",userName);
cmd.Parameters.AddWithValue("@a_IpAddress",ipAddress);
cmd.Parameters.AddWithValue("@a_BlogId",blogId);
cmd.Parameters.AddWithValue("@a_UserId",userId);
getblogPublishedByBlogIdReader = cmd.ExecuteReader();
// There will be only 1 entry.
while (getblogPublishedByBlogIdReader.Read())
{
BlogPublishedByBlogId blogPublishedByBlogId = new BlogPublishedByBlogId();
blogPublishedByBlogIdResults.Status = Convert.ToInt32(getblogPublishedByBlogIdReader["Status"]);
blogPublishedByBlogId.BlogId = Convert.ToInt32(getblogPublishedByBlogIdReader["BlogId"]);
blogPublishedByBlogId.BlogTitle = getblogPublishedByBlogIdReader["BlogTitle"].ToString();
blogPublishedByBlogId.BlogContent = getblogPublishedByBlogIdReader["BlogContent"].ToString();
blogPublishedByBlogId.LikeCount = Convert.ToInt32(getblogPublishedByBlogIdReader["LikeCount"]);
blogPublishedByBlogId.disLikeCount = Convert.ToInt32(getblogPublishedByBlogIdReader["disLikeCount"]);
blogPublishedByBlogId.ModifiedDateTime = Convert.ToDateTime(getblogPublishedByBlogIdReader["ModifiedDateTime"]);
blogPublishedByBlogId.CreatedDateTime = Convert.ToDateTime(getblogPublishedByBlogIdReader["CreatedDateTime"]);
// Test code to see what the value is before trying to convert to boolean below.
int likedisabled = Convert.ToInt32(getblogPublishedByBlogIdReader["Likedisabled"]);
int dislikedisabled = Convert.ToInt32(getblogPublishedByBlogIdReader["disLikedisabled"]);
blogPublishedByBlogId.Likedisabled = Convert.ToBoolean(getblogPublishedByBlogIdReader["Likedisabled"]);
blogPublishedByBlogId.disLikedisabled = Convert.ToBoolean(getblogPublishedByBlogIdReader["disLikedisabled"]);
blogPublishedByBlogIdResults.BlogPublishedByBlogId = blogPublishedByBlogId;
}
return blogPublishedByBlogIdResults;
}
catch (sqlException sqlex)
{
throw sqlex;
}
catch (Exception ex)
{
}
finally
{
if (getblogPublishedByBlogIdReader != null)
{
getblogPublishedByBlogIdReader.Close();
}
dbFunc.CloseDB();
}
}
使用史蒂夫代码的屏幕截图(相同的结果-从存储过程返回的Likedisabled中的整数1仍被转换为值0):
使用史蒂夫代码的屏幕截图(相同的结果-从存储过程返回的Likedisabled中的整数1仍被转换为0值)。另外,存储过程在带有调试选择的SSMS中运行。
解决方法
从逻辑上讲,它应该起作用。 唯一可能性是DisLikeDisabled在Db中为0。 您也可以为此使用替代
blogPublishedByBlogId.LikeDisabled =(getblogPublishedByBlogIdReader["LikeDisabled"] == 1) ? True : False;
,
[编辑2],请尝试使用此修订方法(添加了变量以捕获SqlType):
public BlogPublishedByBlogIdResults GetBlogPublishedByBlogId(string userName,string ipAddress,int blogId,int userId)
{
BlogPublishedByBlogIdResults blogPublishedByBlogIdResults = new BlogPublishedByBlogIdResults();
try
{
dbFunc.OpenDB();
using (SqlCommand sqlCmd = new SqlCommand("dbo.GetBlogPublishedByBlogId",dbFunc.objConn))
{
sqlCmd.CommandType = CommandType.StoredProcedure;
var uName = sqlCmd.Parameters.Add("@a_UserName",SqlDbType.VarChar,255);
uName.Direction = ParameterDirection.Input;
uName.Value = userName;
var ipAddr = sqlCmd.Parameters.Add("@a_IpAddress",255);
ipAddr.Direction = ParameterDirection.Input;
ipAddr.Value = ipAddress;
var blId = sqlCmd.Parameters.Add("@a_BlogId",SqlDbType.Int);
blId.Direction = ParameterDirection.Input;
blId.Value = userName;
var uId = sqlCmd.Parameters.Add("@a_UserName",SqlDbType.Int);
uId.Direction = ParameterDirection.Input;
uId.Value = userName;
using (var sqlDataReader = sqlCmd.ExecuteReader())
{
while (sqlDataReader.Read())
{
// Get the SQL Server raw values by column offset
var sqlStatus = sqlDataReader.GetSqlInt32(0).Value;
var sqlBlogId = sqlDataReader.GetSqlInt32(1).Value;
var sqlBlogTitle = sqlDataReader.GetSqlString(2).Value;
var sqlBlogContent = sqlDataReader.GetSqlString(3).Value;
var sqlLikeCount = sqlDataReader.GetSqlInt32(4).Value;
var sqlDisLikeCount = sqlDataReader.GetSqlInt32(5).Value;
var sqlModDate = sqlDataReader.GetSqlDateTime(6).Value;
var sqlCreateDate = sqlDataReader.GetSqlDateTime(7).Value;
var sqlLikeDisabled = sqlDataReader.GetSqlInt32(8).Value;
var sqlDisLikeDisabled = sqlDataReader.GetSqlInt32(9).Value;
BlogPublishedByBlogId blogPublishedByBlogId = new BlogPublishedByBlogId();
blogPublishedByBlogIdResults.Status = Convert.ToInt32(sqlDataReader["Status"]);
blogPublishedByBlogId.BlogId = Convert.ToInt32(sqlDataReader["BlogId"]);
blogPublishedByBlogId.BlogTitle = sqlDataReader["BlogTitle"].ToString();
blogPublishedByBlogId.BlogContent = sqlDataReader["BlogContent"].ToString();
blogPublishedByBlogId.LikeCount = Convert.ToInt32(sqlDataReader["LikeCount"]);
blogPublishedByBlogId.DisLikeCount = Convert.ToInt32(sqlDataReader["DisLikeCount"]);
blogPublishedByBlogId.ModifiedDateTime = Convert.ToDateTime(sqlDataReader["ModifiedDateTime"]);
blogPublishedByBlogId.CreatedDateTime = Convert.ToDateTime(sqlDataReader["CreatedDateTime"]);
// Test code to see what the value is before trying to convert to boolean below.
int likeDisabled = Convert.ToInt32(sqlDataReader["LikeDisabled"]);
int DislikeDisabled = Convert.ToInt32(sqlDataReader["DisLikeDisabled"]);
blogPublishedByBlogId.LikeDisabled = Convert.ToBoolean(sqlDataReader["LikeDisabled"]);
blogPublishedByBlogId.DisLikeDisabled = Convert.ToBoolean(sqlDataReader["DisLikeDisabled"]);
blogPublishedByBlogIdResults.BlogPublishedByBlogId = blogPublishedByBlogId;
}
return blogPublishedByBlogIdResults;
}
}
}
catch (SqlException sqlex)
{
throw sqlex;
}
catch (Exception ex)
{
}
finally
{
if (getblogPublishedByBlogIdReader != null)
{
getblogPublishedByBlogIdReader.Close();
}
dbFunc.CloseDB();
}
}
您可以尝试使用系统数据类型库。 SqlInt32不会转换为CLR布尔值。将整数作为SqlBoolean返回要容易得多。这是它的实际目的,因为没有BIT这样的“ SQL Boolean”。无论如何,类型库是一个完整的主题。从Sql类型到CLR类型的转换需要进行测试以确保其不为空。
using System.Data.SqlTypes;
然后从DataReader显式转换。如果您知道该值永远不会为空,则可以使用
var yourVar = (bool)sqlDataReader.GetSqlBoolean(0);
如果可以为空,则可以使用
var x = sqlDataReader.GetSqlBoolean(0).IsNull ? false : (bool)sqlDataReader.GetSqlBoolean(0);