首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

自定義數據對象與 DataRow 無縫融合(一):實體層設計

     編輯:關於.NET

ADO.NET DataSet/DataTable/DataRow 功能強但弱類型、非面向對象、體積大。自定義實體類雖強類型、OO,但編寫繁瑣、無法享受數據綁定/離線查詢等便利。本文設計方案:表現層用自定義實體,內部存儲委託 DataRow,兩全其美。

演進歷程

第一版:每實體一 DataTable(性能災難)


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 重對象不可逐實例創建。

第二版:靜態共享 DataTable(失去多態)


public class DataObject
{
    private static DataTable m_dataTable = BuildSchema(); // 靜態
    private DataRow m_dataRow;
    public DataObject() { m_dataRow = m_dataTable.NewRow(); }
    // 無法多態,集合層難以統一處理不同實體類型
}

最終版:抽象基類 + 單例 Schema 容器(完美平衡)


[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; }
    }
}

關鍵優勢

  • 零成本 Schema:單例 DataTable 僅創建一次,所有實例共享。
  • 多態就緒:基類定義 ObjectRow/DataContainer,集合層可統一操作。
  • 序列化透明:基類實現 ISerializable,子類無感知。
  • 代碼生成友好:配合 CodeSmith 模板,根據資料庫 Schema 自動生成實體類,零手寫、零錯誤。
VS2005 測試 100 萬實例,性能與普通對象無異。下篇將實現集合層 ObjectList。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved