我正在检索不同类型的列并在分配类的相应属性之前检查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
}
答案 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
,因为有效的基本类型为byte
,sbyte
,short
,ushort
,int
,{{1} },uint
或long
。
默认类型为ulong
- int
,因此您可以安全地使用默认枚举代码。
SQL Server不支持无符号类型,因此您只需要长时间关注 - Int32
。