ADO.NET DataSet/DataTable/DataRow 功能強但弱類型、非面向對象、體積大。自定義實體類雖強類型、OO,但編寫繁瑣、無法享受數據綁定/離線查詢等便利。本文設計方案:表現層用自定義實體,內部存儲委託 DataRow,兩全其美。
public abstract class AbstractDataObject
{
private DataTable m_dataTable;
private DataRow m_dataRow;
public AbstractDataObject()
{
m_dataTable = BuildSchema(); // 每實例創建 DataTable
m_dataRow = m_dataTable.NewRow();
}
protected abstract DataTable BuildSchema();
// 屬性讀寫委託 m_dataRow["Col"]
}
讀 3 萬行數據導致內存/CPU 暴漲,DataTable 重對象不可逐實例創建。
public class DataObject
{
private static DataTable m_dataTable = BuildSchema(); // 靜態
private DataRow m_dataRow;
public DataObject() { m_dataRow = m_dataTable.NewRow(); }
// 無法多態,集合層難以統一處理不同實體類型
}
[Serializable]
public abstract class DataObjectBase : ISerializable
{
private DataTable m_dataTable;
private DataRow m_dataRow;
public DataRow ObjectRow { get; set; }
public DataTable DataContainer { get; protected set; }
// 序列化:只序列化當前 DataRow
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
DataTable dt = m_dataRow.Table.Clone();
DataRow row = dt.NewRow();
row.ItemArray = m_dataRow.ItemArray;
dt.Rows.Add(row);
info.AddValue("DataTable", dt, dt.GetType());
}
protected DataObjectBase(SerializationInfo info, StreamingContext context)
{
DataTable dt = info.GetValue("DataTable", typeof(DataTable)) as DataTable;
m_dataRow = dt.Rows[0];
}
}
public class DemoDataObject : DataObjectBase
{
// 單例 Schema 容器
private class ObjectSchemaClass
{
public static readonly ObjectSchemaClass Instance = new ObjectSchemaClass();
public DataTable DataContainer;
private ObjectSchemaClass()
{
DataContainer = new DataTable();
DataContainer.Columns.Add("ID", typeof(int));
// ... 其他列
}
}
public DemoDataObject() : base()
{
DataContainer = ObjectSchemaClass.Instance.DataContainer;
ObjectRow = DataContainer.NewRow();
}
public DemoDataObject(DataRow row) { ObjectRow = row; }
protected DemoDataObject(SerializationInfo info, StreamingContext context) : base(info, context) { }
public int ID
{
get { return ObjectRow["ID"] == DBNull.Value ? 0 : (int)ObjectRow["ID"]; }
set { ObjectRow["ID"] = value; }
}
}
DataTable 僅創建一次,所有實例共享。ObjectRow/DataContainer,集合層可統一操作。ISerializable,子類無感知。VS2005 測試 100 萬實例,性能與普通對象無異。下篇將實現集合層 ObjectList。