[英]Generic way of handling DBNull
使用SqlDataReader時,我的代碼中有很多這種類型的邏輯。是否有更干凈的更通用的方式來處理此問題?
if (reader["VisitingAddressId"] != DBNull.Value)
{
visitingAddress = new Address()
{
AddressId = Convert.ToInt64(reader["VisitingAddressId"]),
Address1 = reader["VisitingAddress"].ToString(),
AddressType = AddressType.VisitingAddress,
PostalCode = reader["VisitingPostal"].ToString(),
PostalDistrict = reader["VisitingPostalDistrict"].ToString()
};
}
if (reader["PostalAddressId"] != DBNull.Value)
{
postalAddress = new Address()
{
AddressId = Convert.ToInt64(reader["PostalAddressId"]),
Address1 = reader["PostalAddress"].ToString(),
AddressType = AddressType.PostalAddress,
PostalCode = reader["PostalPostal"].ToString(),
PostalDistrict = reader["PostalPostalDistrict"].ToString()
};
}
我在數據服務類中有這些幫助器方法(可以將它們都設置為靜態):
public T CastDBValue<T>(object value)
{
return MapValue<T>(value);
}
internal static T MapValue<T>(object value)
{
try
{
T result;
result = value == DBNull.Value ? default(T) : (T)value;
return result;
}
catch (InvalidCastException cex)
{
logger.ErrorFormat("Invalid cast while mapping db value '{0}' to type {1}. Error: {2}", value, typeof(T).Name, cex);
throw new InvalidCastException(string.Format("Invalid cast while mapping db value '{0}' to type {1}. Error: {2}", value, typeof(T).Name, cex.Message));
}
}
然后,在您的映射代碼中,您只需執行以下操作:
AddressId = dataService.CastDBValue<int>(reader["AddressId"]));
if (AddressId > 0) { ... }
您可以使用像Dapper這樣的微型ORM: http : //code.google.com/p/dapper-dot-net/
多重映射功能將消除所有樣板代碼。
db.Query<Post,Address,Address,Post>("select * from Posts left join Address ... etc",
(post,vaddress,paddress) =>
{
post.VisitingAddress = vaddress;
post.PostalAddress = paddress;
return post;
});
您所指的是ORM,其中有很多。 NHibernate,Entity Framework甚至ADO.NET(您已經在使用)都支持關系數據集,盡管在這種情況下,您通常必須使用DataSet
或派生的強類型類。
在此處查看.NET部分以獲取列表:
http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software
你有什么要求 也許我們可以縮小范圍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.