在BindFIEldAttribute中,首先我們使用AttributeUsage特性來描述了這個特性的應用范圍,這裡使用了System.AttributeTargets.Property來表明該特性只能用於對象類型的屬性而不能用於其它任何地方。
這裡定義了Name屬性,就是其所依附的數據對象的屬性映射的數據庫字段的名稱,若Name值為空則認為屬性名就是映射的數據庫字段名。若數據對象的屬性沒有附加BindFIEldAttribute特性,則該屬下沒有映射到任何數據庫字段上,框架程序會忽略這個成員屬性的存在。
這裡還定義了Key屬性,用於表明所映射的字段是不是關鍵字段。框架程序在修改和刪除數據庫記錄時需要獲得查詢條件,而對象類型中所有的附加了BindFIEldAttribute特性且Key值為true的屬性就可構造出查詢條件,若對象類型中沒有任何一個Key值為true的成員屬性,則框架程序不能根據其來修改和刪除數據庫記錄。
ReadFormat屬性用於指明從數據庫讀取的原始數據設置到對象屬性值時的解析格式。比如數據庫中保存了類似“20080603”的格式為“yyyyMMdd”的日期數據,而對象屬性的數據類型是DateTime類型。此時我們可以設置ReadFormat值為“yyyyMMdd”則框架程序從數據庫獲得原始數據後試圖用“yyyyMMdd”的格式解析原始數據並獲得一個DateTime值,然後設置到對象屬性值。
WriteFormat屬性類似ReadFormat屬性,用於指明將數據對象的屬性值按照指定的格式化生成一個字符串並保存到數據庫中。
主框架模塊 MyORMFramework類型
類型 MyORMFramework是本ORM框架的主要程序模塊,它根據類型BindTableAttribute和BindFIEldAttribute提供的信息將應用程序對象和數據庫的表和字段進行綁定,然後向數據庫查詢,新增,修改和刪除數據庫記錄。應用程序使用ORM框架也基本上就是創建一個MyORMFramework的實例,然後調用它的成員。
獲得對象-數據庫綁定信息
框架要實現ORM框架功能,第一步就是得獲得應用程序對象和數據庫的映射關系,在MyORMFramework類型中定義了GetBindInfo函數來獲得這種關系。該函數的參數是應用程序的對象類型,返回值是TableBindInfo類型,該類型就是對象-數據庫映射信息。由於BindTableAttribute和BindFieldAttribute類型適合對應用對象類型做標記,但不適合快速查詢信息,因此這裡額外定義了TableBindInfo和FIEldBindInfo類型保存映射關系,這兩個類型的代碼為
/// <summary>
/// 數據表綁定信息對象
/// </summary>
private class TableBindInfo
{
/// <summary>
/// 數據庫表名
/// </summary>
public string TableName = null;
/// <summary>
/// 對象類型
/// </summary>
public Type ObjectType = null;
/// <summary>
/// 綁定信息對象
/// </summary>
public BindTableAttribute Attribute = null;
/// <summary>
/// 綁定的字段信息對象
/// </summary>
public FieldBindInfo[] FIElds = null;
/// <summary>
/// 綁定的字段列表,格式為"字段1,字段2,字段3"
/// </summary>
public string FIEldNameList = null;
}
/// <summary>
/// 數據字段綁定信息對象
/// </summary>
private class FIEldBindInfo
{
/// <summary>
/// 綁定的字段名
/// </summary>
public string FIEldName = null;
/// <summary>
/// 綁定的字段序號
/// </summary>
public int FIEldIndex = - 1;
/// <summary>
/// 對象屬性信息
/// </summary>
public System.Reflection.PropertyInfo Property = null;
/// <summary>
/// 數據類型
/// </summary>
public Type ValueType = null;
/// <summary>
/// 默認值
/// </summary>
public object DefaultValue = null;
/// <summary>
/// 綁定信息對象
/// </summary>
public BindFIEldAttribute Attribute = null;
/// <summary>
/// 將對象數據轉換為數據庫中的數據
/// </summary>
/// <param name="v">對象數據</param>
/// <returns>數據庫數據</returns>
public object ToDataBase( object v )
{
if( v == null || DBNull.Value.Equals( v ))
return DBNull.Value ;
string Format = Attribute.WriteFormat ;
if( Format != null && Format.Trim().Length > 0 )
{
if( v is System.IFormattable )
{
v = ( ( System.IFormattable ) v ).ToString( Format , null );
}
}
return v ;
}
/// <summary>
/// 將從數據庫中獲得的數據轉換為對象數據
/// </summary>
/// <param name="v">從數據庫獲得的原始數據</param>
/// <returns>轉化後的對象數據</returns>
public object FromDataBase( object v )
{
// 若數據為空則返回默認值
if( v == null || DBNull.Value.Equals( v ))
return DefaultValue ;
// 進行格式化解析
string Format = Attribute.ReadFormat ;
if( Format != null && Format.Trim().Length > 0 )
{
string Value = Convert.ToString( v );
if( ValueType.Equals( typeof( DateTime )))
{
if( Format == null )
return DateTime.Parse( Value );
else
return DateTime.ParseExact( Value , Format , null );
}
else if( ValueType.Equals( typeof(byte )))
{
return byte.Parse( Value );
}
else if( ValueType.Equals( typeof( short )))
{
return short.Parse( Value );
}
else if( ValueType.Equals( typeof( int )))
{
return int.Parse( Value );
}
else if( ValueType.Equals( typeof( float )))
{
return float.Parse( Value );
}
else if( ValueType.Equals( typeof( double )))
{
return double.Parse( Value );
}
return Convert.ChangeType( Value , ValueType );
}
if( v.GetType().Equals( ValueType ) || v.GetType().IsSubclassOf( ValueType ))
{
// 若數據類型匹配則直接返回數值
return v ;
}
else
{
// 若讀取的值和對象數據的類型不匹配則進行數據類型轉換
System.ComponentModel.TypeConverter converter =
System.ComponentModel.TypeDescriptor.GetConverter( ValueType );
if( converter != null && converter.CanConvertFrom( v.GetType()) )
{
return converter.ConvertFrom( v ) ;
}
return Convert.ChangeType( v , ValueType );
}
}//public object FromDataBase( object v )
}