代码审查 - 从SqlDataReader中检索数据

时间:2010-06-25 11:18:30

标签: c# ado.net

我正在检索不同类型的列并在分配类的相应属性之前检查null。对于字符串列它一切都很好。但是,我需要决定如何处理DateTime,Bool和Enum类型?

a)我应该为A类使用可空的DateTime属性还是有更好的做法?

b)在下面的代码中检查enum和bool是否正确或者有更好的方法来执行此操作?

 public static List<ClassA> Select(string connectionString)
        {
            List<ClassA> ClassAList = new List<ClassA>();
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                con.Open();
                using (SqlCommand command = new SqlCommand(SPROC_ClassA_Select, con))
                {

                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        int MyGuidOrdinal   = reader.GetOrdinal("MyGuid") ;
                        int MyStringOrdinal = reader.GetOrdinal("MyString") ;
                        int MyDateTimeOrdinal = reader.GetOrdinal("MyDateTime") ;
                        int MyBooleanOrdinal    = reader.GetOrdinal("MyBoolean") ;
                        int MyEnumValueOrdinal  = reader.GetOrdinal("MyEnumValue") ;

                        if(reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                ClassA classA = new ClassA
                                {
                                    MyGuid = reader.GetGuid(MyGuidOrdinal),
                                    MyString = reader["MyString"] is DBNull ? null : reader.GetString(MyStringOrdinal),
                                    MyDateTime = reader["MyDateTime"] is DBNull ? DateTime.MinValue : reader.GetDateTime(MyDateTimeOrdinal),                         
                                    MyBoolean = reader["MyBoolean"] is DBNull ? false : reader.GetBoolean(MyBooleanOrdinal),          
                                    MyEnumValue = reader["MyEnumValue"] is DBNull ? (int)MyEnumValue.Value1 : reader.GetInt32(MyEnumValueOrdinal),

                                };

                                ClassAList.Add(classA);
                            }
                        }
                        return ClassAList;

                    }


                }
            }

以下是枚举: -

public enum MyEnumValue 
{
 value1 =1,
 value2
}

6 个答案:

答案 0 :(得分:3)

如果您希望您的类能够正确地维护数据库值而不会丢失,那么您应该将可空类型用于布尔值,日期和可能的枚举值。否则,如果将数据发送回数据库,则在更新数据时可能会将所有空值更改为默认值。

另外,如果您使用reader.IsDBNull()来检查空值,那么代码会不会更好一些?

答案 1 :(得分:3)

a)这取​​决于你希望应用程序做什么,如果你有一个有效的默认值(大多数使用DateTime.Now)然后使用它,否则使它可以为空。

b)如果false是有效的默认值,则bool正常,否则使其可以为空。使用GetByte获取枚举并将其强制转换为枚举类型。

(MyEnumValue)reader.GetByte(MyEnumValueOrdinal)

注意:如果这些列中的任何一列在您的数据库中不可为空,请不要在您的类中使其可为空,甚至不检查DBNull。

答案 2 :(得分:1)

a)我个人更喜欢返回可以为空的DateTime值,因为我觉得这是对数据库字段状态的更好抽象(而不是必须检查DateTime.MinValue)。

b)中 将false作为DBNull的表示可能与您的业务逻辑匹配,如果没有,那么我将再次使用可空类型。

枚举转换可能会让您失望 - 您可能希望使用Enum.IsDefined(typeof(MyEnumValue), reader["MyEnumValue"])

验证结果

此外,我会将所有字段名称定义为字符串常量,以避免输入错误(并且intellisense也会为您提供自动完成功能)。

赫比

答案 3 :(得分:1)

当Nullable属性对应于数据库中的可空列时,可以使用Nullable属性。

以下代码与您的代码大致相同,但更短:

MyString = reader["MyString"] is DBNull ? null : (string)reader["MyString"]

答案 4 :(得分:0)

Nullable DateTime和Nullable Boolean可以在这里使用,在你指定false时,调用者无法知道它是否是假的,或者它是未知的。

同样使用DateTime.MinValue,调用者可能会看到某些东西正在销售中(例如,它的'Sell From'日期是MinValue),实际上它在DB中为NULL以防止它被出售。< / p>

请注意,您也可以使用Nullable Enums,但由于您需要对其进行常量.Value请求,因此它们不是很好。所以这可能是更好的选择:

public enum MyEnumValue 
{
 ItWasNullInTheDB = 0,
 value1 =1,
 value2
}

答案 5 :(得分:0)

小心Enum,因为有效的基本类型为bytesbyteshortushortint,{{1} },uintlong。 默认类型为ulong - int,因此您可以安全地使用默认枚举代码。 SQL Server不支持无符号类型,因此您只需要长时间关注 - Int32