【问题标题】:Specified cast is not valid converting INT to ENUM with SqlDataReader使用 SqlDataReader 将 INT 转换为 ENUM 指定转换无效
【发布时间】:2013-05-02 22:14:09
【问题描述】:

编辑

删除assetItem 上的对象初始化器似乎解决了我的问题,但为什么呢?

结束编辑

我似乎无法找到一种方法来从我的数据库中读取一个 INT 并将其转换为 emun。

我已经尝试了这两个建议 Cast int to enum in C#How to (efficiently) convert (cast?) a SqlDataReader field to its corresponding c# type? 没有成功。

using (var connection = new SqlConnection(_sqlstring))
{
    using (var command = new SqlCommand("EXEC GetAllEncodedMedia", connection))
    {
        try
        {
            connection.Open();
            var reader = command.ExecuteReader();
            while (reader.Read())
            {
                if (reader.HasRows)
                {
                    var assetItem = new MediaServices.EncodedAssets
                    {
                        Id = reader.IsDBNull(0) ? 0 : reader.GetInt32(0),
                        PublishedName = reader.IsDBNull(1) ? null : reader.GetString(1),
                        PublishUri = reader.IsDBNull(2) ? new Uri("http://www.null.com") : new Uri(reader.GetString(2)),
                        EncodePreset = reader.IsDBNull(3) ? 0 : (MediaServices.EncodePresetsForSmoothStreaming)reader.GetInt32(3),
                        AssetId = reader.IsDBNull(4) ? null : reader.GetString(4),
                        EncoderJobId = reader.IsDBNull(5) ? 0 : reader.GetInt32(5),
                        //EncoderState = reader.IsDBNull(6) ? 0 : (JobState)reader.GetInt32(6),
                        //AssetState = reader.IsDBNull(7) ? 0 : (MediaServices.InternalAssetState)reader.GetInt32(7),
                        GroupId = reader.IsDBNull(8) ? 0 : reader.GetInt32(8),
                        Published = !reader.IsDBNull(2)
                    };
                    listReturn.Add(assetItem);
                }
            }
        }
        catch (Exception ex)
        {
            //error
        }

    }
}



[DataContract]
public enum EncodePresetsForSmoothStreaming
{
    [EnumMember]
    [Description("H264 Smooth Streaming 1080p")]
    H264SmoothStreaming1080P,
    [EnumMember]
    [Description("H264 Smooth Streaming 720p")]
    H264SmoothStreaming720P,
    [EnumMember]
    [Description("H264 Smooth Streaming 720p for 3G or 4G")]
    H264SmoothStreaming720Pfor3Gor4G,
    [EnumMember]
    [Description("H264 Smooth Streaming SD 16x9")]
    H264SmoothStreamingSd16X9,
    [EnumMember]
    [Description("H264 Smooth Streaming SD 4x3")]
    H264SmoothStreamingSd4X3

}

如何将序数 3 (int) 转换为 EncodePresetsForSmoothStreaming (enum)?

【问题讨论】:

  • 我认为你不需要在 while 循环中检查 if (reader.HasRows) 因为你已经调用了 reader.Read() 这意味着你已经读取了一行(这意味着有行)。
  • 如果您在结果集第 3 列中有任何 null 值,您会得到。
  • 我的数据库的内容(当前)没有空值。我检查空值的此代码的先前版本会产生相同的错误
  • 整数真的代表一个枚举吗?例如。你有 enum Test { A, B } 并且你正在读取的整数值是 9999。
  • 通过引用同一个 emum 将值写入数据库,检查数据库,值在愤怒中。但是我发现删除数据库读取和强类型枚举本身会产生相同的转换错误。所以我现在很困惑

标签: c# casting


【解决方案1】:

尝试如下声明您的枚举,这应该允许它正确地从整数转换为正确的枚举值。

public enum Test : int 
{ 
   TestValue1 = 1, 
   TestValue2 = 2, 
   TestValue3 = 3
}

【讨论】:

    【解决方案2】:

    你在那里缺少 reader.IsDBNull(3),所以它可能试图将 DbNull 转换为 int,这是无效的。

    如果您确定该列中没有空值,请确保您从数据库中获取的是 int,您可以通过将内容获取为字符串来做到这一点;或将其保留为对象,设置断点,并在 IDE 调用 value.GetType() 中使用即时窗口,它会告诉你到底在处理什么。

    如果您将枚举作为字符串存储在数据库中,那么您应该使用 Enum.Parse()

    这也是类似的:Exception: Specified cast is not valid

    【讨论】:

    • 我的数据库的内容(当前)没有空值。我检查空值的此代码的先前版本会产生相同的错误。我将更新我的示例
    • +1 for You're missing reader.IsDBNull(3) there 即使 OP 只是将代码偷偷放在那里。
    • 没有什么可以“偷偷摸摸”的。你在发布之前尝试不同的东西。要尝试的许多事情之一是删除空检查(当然是新手操作)
    • @Damo 尝试使用即时窗口来确定您从 DB 获取的对象类型
    • @Damo 是的,有。您发布的是实际代码,而不是它的一些破解版本。
    【解决方案3】:

    将命令的类型更改为存储过程,并从命令文本中删除“EXEC”,以便命令文本只是存储过程名称:

    using (var connection = new SqlConnection(_sqlstring))
    {
        using (var command = new SqlCommand("GetAllEncodedMedia", connection))
        {
            try
            {
                connection.Open();
                command.CommandType = CommandType.StoredProcedure;
                var reader = command.ExecuteReader();
                while (reader.Read())
                {
                    if (reader.HasRows)
                    {
                        var assetItem = new MediaServices.EncodedAssets
                        {
                            Id = reader.IsDBNull(0) ? 0 : reader.GetInt32(0),
                            PublishedName = reader.IsDBNull(1) ? null : reader.GetString(1),
                            PublishUri = reader.IsDBNull(2) ? new Uri("http://www.null.com") : new Uri(reader.GetString(2)),
                            EncodePreset = reader.IsDBNull(3) ? 0 : (MediaServices.EncodePresetsForSmoothStreaming)reader.GetInt32(3),
                            AssetId = reader.IsDBNull(4) ? null : reader.GetString(4),
                            EncoderJobId = reader.IsDBNull(5) ? 0 : reader.GetInt32(5),
                            //EncoderState = reader.IsDBNull(6) ? 0 : (JobState)reader.GetInt32(6),
                            //AssetState = reader.IsDBNull(7) ? 0 : (MediaServices.InternalAssetState)reader.GetInt32(7),
                            GroupId = reader.IsDBNull(8) ? 0 : reader.GetInt32(8),
                            Published = !reader.IsDBNull(2)
                        };
                        listReturn.Add(assetItem);
                    }
                }
            }
            catch (Exception ex)
            {
                //error
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      仔细检查列的数据类型,枚举可能存储为tinyint。 How can you convert "tinyint" of t-sql to integer in c#?

      在强制转换之前尝试将值读取到变量中,以验证错误不是读数。

      【讨论】:

        猜你喜欢
        • 2011-08-30
        • 2018-12-13
        • 1970-01-01
        • 2017-08-25
        • 2015-04-12
        • 2020-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多