Object/DataSet Relational Mapping(对象/数据集关系映射)

在.Net的开发领域,您和您的公司是不是在为以下问题所困扰


1.DataSet中DataRow只能以DataTable[0].Rows[0][“Name”]的方式获取数据


2.Sql配置的不动态,不清晰的Sql拼凑


3.使用JAVA 的ORM设计.Net,使用对象层,每一次修改都将影响反射的对象。


那么请继续看下面的文章


Object/DataSet Relational Mapping


(对象/数据集关系映射)


NickLee.ODRM模式可以很好的解决以上问题


1.DataSet中DataRow只能以DataTable[0].Rows[0][“Name”]的方式获取数据


方案:DataRow转化为序列化对象,但序列化对象只作为清晰的对象操作实体处理业务判断和数据


2.Sql配置的不动态,不清晰的Sql拼凑


方案:采用IBatisNet数据层构架,采用IBatisNet动态的SQL语法,但返回DataSet


3.使用JAVA 的ORM设计.Net,使用对象层,每一次修改都将影响反射的对象。


方案:清晰的O(对象层),无反射机制,避免每一次修改对对象层的改动。


下面做详细的说明


       以下代码演示将包含在NickLee.Framework.2.0.1.2以上版本中,当然,我们只是提供一种思想,灵活的方案,仅代表TheFallAngel团队的思想。


       必须引用的dll


       IBatisNet(Version 1.5及其以后) with NickLee.Framework修改版本


       NickLee.Web.UI(Version 2006.2.1447及其以后版本)


1.      cXTM_User.cs


using System;


using System.Data;


using System.Configuration;


using System.Web;


using System.Web.Security;


using System.Web.UI;


using System.Web.UI.WebControls;


using System.Web.UI.WebControls.WebParts;


using System.Web.UI.HtmlControls;


 


/// <summary>


/// cXTM_User.序列化


/// </summary>


[Serializable]


public class cXTM_User


{


    private int _dID;


    private string _userName;


    public cXTM_User()


    {


        //


        // TODO: 在此处添加构造函数逻辑


        //


    }


    public int DID


    {


        get


        {


            return _dID;


        }


        set


        {


            _dID = value;


        }


    }


    public string UserName


    {


        get


        {


            return _userName;


        }


        set


        {


            _userName = value;


        }


    }


    /// <summary>

#p#副标题#e#


    /// Propertylist中数组请定义该类中属性,并确保名称唯一性


    /// 以及与XTM_User中SelectXTM_UserByKey_Test中查询名称统一


    /// </summary>


    public string[] Propertylist


    {


        get


        {


            return new string[] { “UserName”, “DID” };


        }


    }


}


2.      XTM_User.xml


<?xml version=’1.0′ encoding=’UTF-8′ ?>


<sqlMap namespace=’XTM_User’ xmlns=”http://ibatis.apache.org/mapping” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>


<statements>


         <select id=’SelectXTM_UserByKey_Test’ parameterClass=’System.Collections.Hashtable’>


                   SELECT


                            Top 5


                            [DID],


                            [UserName],


                            [LoginName],


                            [PWD],


                            [LoginFlag],


                            [StopFlag],


                            [LoginTime],


                            [LASTUPDATE]


                   FROM [XTM_User]


         </select>


</statements>


</sqlMap>


 


3.      test.aspx


<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”test.aspx.cs” Inherits=”ODRM_test” %>

#p#副标题#e#


<%@ Register Assembly=”NickLee.Web.UI” Namespace=”NickLee.Web.UI” TagPrefix=”NickLee” %>


<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>


<html xmlns=”http://www.w3.org/1999/xhtml” >


<head runat=”server”>


    <title>Object/DataSet Relational Mapping(对象/数据集关系映射)</title>


</head>


<body>


    <form id=”form1″ runat=”server”>


    <div>


        <NickLee:ExDataGrid ID=”ExDataGrid1″ runat=”server” OnItemDataBound=”ExDataGrid1_ItemDataBound”>


        </NickLee:ExDataGrid></div>


    </form>


</body>


</html>


4.      test.aspx.cs


using System;


using System.Data;


using System.Configuration;


using System.Collections;


using System.Web;


using System.Web.Security;


using System.Web.UI;


using System.Web.UI.WebControls;


using System.Web.UI.WebControls.WebParts;


using System.Web.UI.HtmlControls;


 


using IBatisNet.DataMapper;


using System.Reflection;


 


public partial class ODRM_test : PageBase


{


    protected void Page_Load(object sender, EventArgs e)


    {


        if (!IsPostBack)


        {


            DataSet set11 = Mapper.Instance().QueryForDataSet(“SelectXTM_UserByKey_Test”,UIhashtable);


            DataTable table1 = ConvertDataTable(set11, “”);


            //这里为自己定义的序列化类


            cXTM_User[] objModel = new cXTM_User[table1.Rows.Count];


            //DataTable转化为序列化类数组


            for (int y = 0; y < table1.Rows.Count; y++)


            {


                objModel[y] = new cXTM_User();


                DataTableReturnOO(table1.Rows[y], objModel[y]);


            }


            //以DataSet模式绑定


            ExDataGrid1.DataSource = table1;


            //以序列化对象模式绑定


            //ExDataGrid1.DataSource = objModel;


            ExDataGrid1.DataBind();

#p#副标题#e#


        }


    }


 


    protected void ExDataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)


    {


        /*


         * 该部分应用范围


         * 查询一条数据的修改,可以用objModel.UserName


         * 而不必再使用DataTable[0].Rows[0][“UserName”]的模式


         * 提高面向对象的程度,并减少业务流程部分编码


         */


 


        if (e.Item.ItemIndex != -1)


        {


            cXTM_User objModel = new cXTM_User();


           


            //如果为DataSet填充的DataGrid


            if (e.Item.DataItem.GetType().FullName == “System.Data.DataRowView”)


            {


                DataTableReturnOO((DataRow)((DataRowView)e.Item.DataItem).Row, objModel);     


            }


            //否则认为为序列化对象填充


            else


            {


                objModel = (cXTM_User)e.Item.DataItem;


                  


            }


        }


    }


 


    /// <summary>


    /// DataSet转化为序列化类函数,类定义参考cXTM_User


    /// </summary>


    private void DataTableReturnOO(DataRow row, cXTM_User objModel)


    {


        Hashtable hTable = new Hashtable();


        hTable = ReturnHashtable(row);


 


        Type entitytype = Type.GetType(objModel.GetType().AssemblyQualifiedName);


 


        for (int j = 0; j < objModel.Propertylist.Length; j++)


        {


            PropertyInfo propertyinfo = entitytype.GetProperty(objModel.Propertylist[j]);

#p#副标题#e#


            propertyinfo.SetValue(objModel, hTable[objModel.Propertylist[j]], null);


        }


 


    }


 


    /// <summary>


    /// 转换为DataTable


    /// </summary>


    /// <param name=”Source”>数据源</param>


    /// <param name=”DataMember”>数据表名称</param>


    public static DataTable ConvertDataTable(object Source, string DataMember)


    {


        DataTable baseTable = new DataTable();


        if (Source is DataTable)


        {


            baseTable = (DataTable)Source;


            return baseTable;


        }


        if (Source is DataSet)


        {


 


            DataSet set1 = (DataSet)Source;


            if ((set1.Tables.Count > 1) && ((DataMember == null) || (DataMember == “”)))


            {


                throw new Exception(“If there is more than one table in your dataset, you must define the DataMember property to specify which table to use.”);


            }


            if (set1.Tables.Count < 1)


            {


                throw new Exception(“There are no tables in the datasource.”);


            }


            if ((DataMember != null) && (DataMember != “”))


            {


                baseTable = set1.Tables[DataMember];


                return baseTable;


            }


            else


            {


                baseTable = set1.Tables[0];


                return baseTable;

#p#副标题#e#


            }


          


        }


        return baseTable;


    }


 


    /// <summary>


    /// 返回DataTable为哈希表键值对


    /// </summary>


    /// <param name=”SourceTable”>数据行对象</param>


    /// <returns></returns>


    public static Hashtable ReturnHashtable(DataRow SourceRow)


    {


        Hashtable hTable = new Hashtable();


        IList list = SourceRow.ItemArray;


        object[] tObj = new object[SourceRow.Table.Columns.Count];


 


        for (int i = 0; i < SourceRow.Table.Columns.Count; i++)


        {


            tObj[SourceRow.Table.Columns.IndexOf(SourceRow.Table.Columns[i].ColumnName)] = SourceRow.Table.Columns[i].ColumnName;


        }


 


        for (int x = 0; x < list.Count; x++)


        {


            hTable.Add(tObj[x].ToString(), list[x]);


        }


        return hTable;


    }


 


}


5.      PageBase.cs


using System;


using System.Data;


using System.Configuration;


using System.Web;


using System.Web.Security;


using System.Web.UI;


using System.Web.UI.WebControls;


using System.Web.UI.WebControls.WebParts;


using System.Web.UI.HtmlControls;


 


using System.Reflection;


using System.Text;


using System.Collections;


 


//namespace可要可不要


//namespace Framework.Web.UIProcess


//{


/// <summary>


/// PageBase 的摘要说明


/// </summary>


/// <summary>


/// 页面层(表示层)基类,所有页面继承该页面


/// </summary>


    public class PageBase : System.Web.UI.Page


    {


 


 


        #region 整个系统存在部分


        private string _baseselect;


        /// <summary>


        /// 查询字段


        /// </summary>


        protected string baseselect


        {


            get


            {


                // TODO: 添加 BaseRule.OperationCode getter 实现

#p#副标题#e#


                return _baseselect;


            }


            set


            {


                // TODO: 添加 BaseRule.OperationCode setter 实现


                _baseselect = value;


            }


        }


        /// <summary>


        /// 基类哈希表,在整个系统中存在


        /// </summary>


        protected Hashtable baseHashtable = new Hashtable();


        /// <summary>


        /// 界面哈希表,获取UI工厂获取的控件和控件值


        /// </summary>


        protected Hashtable UIhashtable = new Hashtable();


        /// <summary>


        /// 出错提示,默认值””


        /// </summary>


        protected string errMsg = “”;


        /// <summary>


        /// 出错状态,默认值false


        /// </summary>


        protected bool errState = false;


        /// <summary>


        /// 私有变量_UISet


        /// </summary>


        private DataSet _UISet = new DataSet();


        /// <summary>


        /// 界面层数据集


        /// </summary>


        protected DataSet UISet


        {


            get


            {


                // TODO: 添加 BaseRule.OperationCode getter 实现


                return _UISet;


            }


            set


            {

#p#副标题#e#


                // TODO: 添加 BaseRule.OperationCode setter 实现


                _UISet = value;


            }


        }


        private DataTable _UITable = new DataTable();


        /// <summary>


        /// 界面层数据表


        /// </summary>


        protected DataTable UITable


        {


            get


            {


                // TODO: 添加 BaseRule.OperationCode getter 实现


                return _UITable;


            }


            set


            {


                // TODO: 添加 BaseRule.OperationCode setter 实现


                _UITable = value;


            }


        }


 


        private string _pageTitle = “”;


        /// <summary>


        /// 页面标题


        /// </summary>


        protected string pageTitle


        {


            get


            {


                // TODO: 添加 BaseRule.OperationCode getter 实现


                return _pageTitle;


            }


            set


            {


                // TODO: 添加 BaseRule.OperationCode setter 实现


                _pageTitle = value;


            }

#p#副标题#e#


        }


        #endregion


 


        #region 查询页面存在部分


        /// <summary>


        /// List页面基类哈希表


        /// </summary>


        protected Hashtable baseListHashtable = new Hashtable();


        /// <summary>


        /// 页面总数.变量.1000w、10000w数据集使用


        /// </summary>


        protected int pageCount;


 


        /// <summary>


        /// 记录总数.变量.1000w、10000w数据集使用


        /// </summary>


        protected int recordCount;


        /// <summary>


        /// 记录总数.属性.1000w、10000w数据集使用


        /// </summary>


        protected int RecordCount


        {


            get


            {


                return recordCount;


            }


        }


        #endregion


 


        #region 编辑页面存在部分


        /// <summary>


        /// Edit页面基类哈希表


        /// </summary>


        protected Hashtable baseEditHashtable = new Hashtable();


        /// <summary>


        /// Edit页面,编辑数据哈希表


        /// </summary>


        protected Hashtable baseEditFillHashtable = new Hashtable();


        #endregion


 


 


        /// <summary>


        /// 构造函数


        /// </summary>


        public PageBase()


        {


            this.Load += new EventHandler(PageBase_Load);


        }

#p#副标题#e#


 


        private void PageBase_Load(object sender, EventArgs e)


        {


            if (!Page.IsPostBack)


            {


 


                //整个流程需要的控制部分


                if (Session[“baseHashtable”] != null)


                {


                    //从Session中获取哈希对象列表


                    baseHashtable = (Hashtable)Session[“baseHashtable”];


                }


 


                //编辑页面访问权限和访问控制,只在第一次载入页面的时候有效


                if (Session[“baseEditHashtable”] != null)


                {


                    //获取Edit页面哈希对象列表


                    baseEditHashtable = (Hashtable)Session[“baseEditHashtable”];


                    //获取完后释放对应Session对象


                    Session.Remove(“baseEditHashtable”);


                }


                else


                {


                    //如果为初始状态,新增是否安全编辑状态值,默认值false,不安全


                    baseEditHashtable.Add(“EditSafeState”, false);


                }


            }


 


            //查询页面访问控制


            if (Session[“baseListHashtable”] != null)

#p#副标题#e#


            {


                //获取Edit页面哈希对象列表


                baseListHashtable = (Hashtable)Session[“baseListHashtable”];


                //获取完后释放对应Session对象


                Session.Remove(“baseListHashtable”);


            }


            else


            {


                //如果为初始状态,新增是否刷新查询页面,默认值false,不刷新


                baseListHashtable.Add(“IsRefresh”, false);


            }


        }


 


 


        #region UI通用函数


        /// <summary>


        /// 抛出出错消息提示


        /// </summary>


        /// <param name=”page”>页面</param>


        /// <param name=”errMsg”>出错消息</param>


        protected void throwErrMsg(Page page, string errMsg)


        {


            page.Response.Write(“<script>window.alert(\”” + errMsg.Replace(“\””, “‘”) + “\”);</script>”);


        }


 


        /// <summary>


        /// 刷新打开编辑窗体的List页面


        /// </summary>


        /// <param name=”page”>页面</param>


        protected void parentPageRefresh(Page page)


        {


            StringBuilder scriptString = new StringBuilder();


            scriptString.Append(“<script language = javascript>”);


            //调用Function.js中的refresh()刷新父窗体


            scriptString.Append(“window.opener.refresh(false,\”\”);”);


 


            scriptString.Append(” window.focus();”);

#p#副标题#e#


            scriptString.Append(” window.opener=null;”);


            scriptString.Append(” window.close(); “);


 


            scriptString.Append(“</” + “script>”);


            page.Response.Write(scriptString.ToString());


        }


 


        /// <summary>


        /// 重置页面


        /// </summary>


        /// <param name=”page”>页面</param>


        protected void pageReset(Page page)


        {


            StringBuilder scriptString = new StringBuilder();


            scriptString.Append(“<script language = javascript>”);


 


            scriptString.Append(” this.location.reset(); “);


 


            scriptString.Append(“</” + “script>”);


            page.Response.Write(scriptString.ToString());


        }


 


        /// <summary>


        /// js界面工厂传入后生成Hashtable


        /// </summary>


        /// <param name=”splitStr”>js界面工厂传入字符串</param>


        /// <returns></returns>


        public Hashtable AjaxUIFactory(string splitStr)


        {


            string[] fristStr = splitStr.Split(‘,’);


            Hashtable table = new Hashtable();


            for (int x = 0; x < fristStr.Length; x++)


            {


                string[] secondStr = fristStr[x].Split(‘|’);


                if (secondStr.Length == 3)


                {


                    //取截取后字符串和值


                    table.Add(secondStr[1], secondStr[2]);

#p#副标题#e#


                }


            }


            return table;


        }


        #endregion


}