国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

用基礎知識實現數據到模型的填充

2019-11-14 16:40:13
字體:
來源:轉載
供稿:網友

  目前的開發(fā)中,我們一般會從數據庫查詢出來數據,再把數據填充到一個對象中,然后就可以很方便的讀取對象信息了。data填充到object這個過程很是繁瑣,為簡化這個問題,各種框架、組件層出不窮,在此不一一列舉,我實在也列舉不出 -_- !  諸多框架用起來固然方便,但我總會想起一句話,原文模糊了,出處忘了,大意是“當到一定程度時技術都會以各自的方式失敗”,且不說失敗不失敗,用框架的同學在某個時刻肯定有過這樣的感慨:“要是這個框架支持XX就好了”、“這個功能本來很簡單,但我們項目現在用的是這個框架,要實現這個功能看來又要寫蹩足的代碼了”、“這個框架越來越不符合我們的要求,難道我們要改成YY框架嗎?”等等。所以框架都有自身固有的限制,那么我們面臨的問題,第一時間真的都要求助于框架嗎?

本文想表達的決無輕視框架的意思,只是園里討論框架的甚多,往往讓新手有一種不了解、不會用某某框架就說明自己差人一大截的感覺,同時也讓很多新手只因會用很多框架就感覺自己很牛B的樣子,不管是哪種情況,都不利于自身技術上的提高。所以此文是只是希望新手們能深刻思考一下自己的現狀,給自己一個正確的評估,努力做到看到如何調用時,就大概能想象出內部是如何實現的,說白了就是對語言本身很熟悉,對一些思想有了解,下面不表框架的種種,單用新手都知道的技術組合出一個data到object的實現。

準備及問題:

  準備1,數據庫test1有表MyUser{

    ID (PK, int, not null)  

    UserName (varchar(20), not null)

    Age (tinyint, not null)

    Birthday (datetime, null)

    }

  準備2,數據庫test2有表Message{

    ID (PK, int, not null)

    MyUserID (int, not null)

    Content (nvarchar(200), not null)

    AddTime (datetime, not null)

  }

      準備3,SQLHelper一個,這個自不必說,訪問數據庫嘛!

  問題1,一個data到object的填充只實現一次,不管是取多少個字段,不管是取一條數據還是多條數據

  問題2,關聯查詢,為了強調演示,關聯數據在不同的數據庫里,具體就是查用戶和他們的消息(可能用動態(tài)和評論來舉例更合適,呵呵 諒解?。?/p>

 思考:

  想重用,自然而然的就會想到繼承;

  想統一處理,也要想到抽象;

  想動態(tài)添加數據,要能想到字典,大家一定要記得,字典是一個很好用的數據結構;

  想用統一的方法得到不同的具體的類型對象,自然是泛型了。

  下方會一一體現,現在不明所以沒關系。

 實現:

  data到object的填充,具體到ado.net,一般就是reader到object了,要實現動態(tài)字段都用一個方法填充,以MyUser來說,大概可以這樣:

public MessageInfo FillModelFromReader(DbDataReader reader, params string[] fields)        {            var info = new MessageInfo();            if (DALUtil.HasFields("ID", fields)) { info.ID = (int)reader["ID"]; }            if (DALUtil.HasFields("MyUserID", fields)) { info.MyUserID = (int)reader["MyUserID"]; }            if (DALUtil.HasFields("Content", fields)) { info.Content = reader["Content"].ToString(); }            if (DALUtil.HasFields("AddTime", fields)) { info.AddTime = (DateTime)reader["AddTime"]; }            return info;        }

   數據庫交互無非就那幾個方法,我們可以抽象出來一個數據訪問的基類,實際運用中還要寫幾個方法重載,以便于調用

    /// <summary>    /// DAL基類    /// </summary>    /// <typeparam name="T"></typeparam>    public abstract class DALBase<T>    {        /// <summary>        /// 由子類決定用哪個鏈接        /// </summary>        PRotected abstract string ConnName        {            get;        }        protected abstract T FillModelFromReader(DbDataReader reader, params string[] fields);        protected string GetConnStr()        {            return System.Configuration.ConfigurationManager.ConnectionStrings[ConnName].ConnectionString;        }        protected List<T> FindList(string sql, CommandType type, params SqlParameter[] parameters)        {            using (var reader = SqlHelper.ExecuteReader(GetConnStr(), type, sql, parameters))            {                List<T> list = new List<T>();                var fields = DALUtil.GetReaderFieldNames(reader);                while (reader.Read())                {                    list.Add(FillModelFromReader(reader, fields));                }                return list;            }        }        protected T FindOne(string sql, CommandType type, params SqlParameter[] parameters)        {            return FindList(sql, type, parameters).FirstOrDefault();        }        private List<T> FindPage(string tableName, string fields, string query, string orderby, int pageIndex, int pageSize, bool isTotal, out int totalCount, params SqlParameter[] parameters)        {            if (pageIndex < 1)            {                throw new ArgumentException("pageIndex參數應>1");            }            StringBuilder sb = new StringBuilder();            SqlParameter[] newps;            if (isTotal)            {                sb.AppendFormat("select count(0) from [{0}]", tableName);                if (!string.IsNullOrWhiteSpace(query))                {                    sb.AppendFormat(" where {0}", query);                }                totalCount = GetCount(sb.ToString(), parameters);                sb.Clear();                newPs = SqlHelper.CopyParameters(parameters);            }            else            {                newPs = parameters;                totalCount = 0;            }            if (string.IsNullOrWhiteSpace(orderby))            {                throw new ArgumentException("orderby參數不應為空");            }            var fs = string.IsNullOrWhiteSpace(fields) ? "*" : string.Join(",", fields);            sb.AppendFormat("select {0} from (", fs);            sb.AppendFormat(" select top {0} {1},ROW_NUMBER() over(order by {2}) rowid from {3}", pageIndex * pageSize, fs, orderby, tableName);            if (!string.IsNullOrWhiteSpace(query))            {                sb.AppendFormat(" where {0}", query);            }            sb.AppendFormat(")t where t.rowid>{0} and t.rowid<={1}", (pageIndex - 1) * pageSize, pageIndex * pageSize);            return FindList(sb.ToString(), CommandType.Text, newPs);        }        protected object GetScalar(string sql, CommandType type, params SqlParameter[] parameters)        {            return SqlHelper.ExecuteScalar(GetConnStr(), type, sql, parameters);        }        protected int GetCount(string sql, CommandType type, params SqlParameter[] parameters)        {            var obj = GetScalar(sql, type, parameters);            if (obj == null) return -1;            return (int)obj;        }        protected int Execute(string sql, CommandType type, params SqlParameter[] parameters)        {            return SqlHelper.ExecuteNonQuery(GetConnStr(), type, sql, parameters);        }    }
View Code

   實現MyUserDAL,繼承于DALBase<MyUserInfo>,設置自己的鏈接名,實現自己的填充方法,而所有的查詢直接調用基類的方法即可,不管哪個查詢,都會在基類調用自己實現的填充方法!這樣問題1算是解決了。(模型和FillModelFromReader都是用MyGeneration)

public class MyUserDAL : DALBase<MyUserInfo>    {        protected override string ConnName        {            get { return "sqlconn1"; }        }        protected override MyUserInfo FillModelFromReader(DbDataReader reader, params string[] fields)        {            var info = new MyUserInfo();            if (DALUtil.HasFields("ID", fields)) info.ID = (int)reader["ID"];            if (DALUtil.HasFields("UserName", fields)) info.UserName = reader["UserName"].ToString();            if (DALUtil.HasFields("Age", fields)) info.Age = (byte)reader["Age"];            if (DALUtil.HasFields("Birthday", fields) && !(reader["Birthday"] is DBNull)) info.Birthday = (DateTime)reader["Birthday"];            return info;        }        public MyUserInfo FindOne(int id)        {            var sql = "select * from MyUser where ID=@id";            return FindOne(sql, DALUtil.CreateParameter("id", id));        }        public List<MyUserInfo> Find1()        {            var sql = "select ID,UserName from MyUser";            return FindList(sql);        }        public List<MyUserInfo> Find2()        {            var sql = "select ID,UserName,Age,Birthday from MyUser";            return FindList(sql);        }    }

  問題2是表關聯問題,這個時候要想到字典,字典這個東西真是再強調也不為過啊。對于UI層,我們取數據是從模型來的,所以關聯數據也要在模型上,我們?yōu)樾枰P聯數據的模型建一個基類,關聯數據其實可以理解為附加數據的一種,所以我們以后叫它附加數據:

    /// <summary>    /// 模型層附加數據基類    /// </summary>    [Serializable]    public class ModelBase    {        private Dictionary<string, object> _exData = new Dictionary<string, object>();        public Dictionary<string, object> ExData        {            get { return _exData; }            set { _exData = value; }        }        /// <summary>        /// 得到附加數據        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="name"></param>        /// <returns></returns>        public T GetExData<T>(string name)        {            object data;            if (_exData.TryGetValue(name, out data))            {                return (T)data;            }            return default(T);        }        /// <summary>        /// 添加附加數據        /// </summary>        /// <param name="name"></param>        /// <param name="obj"></param>        public void AddExData(string name, object obj)        {            _exData.Add(name, obj);        }        /// <summary>        /// 檢測附加數據是否存在        /// </summary>        /// <param name="name"></param>        /// <returns></returns>        public bool ExistsExData(string name)        {            return _exData.ContainsKey(name);        }    }

  MyUserInfo有附加數據,那么就讓MyUserInfo繼承ModelBase吧,繼承后便有了存儲附加數據的能力,而附加數據這個操作寫到哪里呢?當然是寫到BLL里,首先實現Message的相關功能,這里我們需要一個public List<MessageInfo> FindByUserIDs(IEnumerable<int> userids)的方法來根據一串userid得到一個MessageInfo的集合,代碼不貼了,下附下載。直接看MyUserBLL里的操作:

    public class MyUserBLL    {        DAL.MyUserDAL dal = new DAL.MyUserDAL();        public MyUserInfo FindOne(int id)        {            return dal.FindOne(id);        }        public List<MyUserInfo> Find1()        {            var list = dal.Find1();            return list;        }        public List<MyUserInfo> Find2()        {            var list = dal.Find2();            DealMsg(list);            return list;        }        static void DealMsg(List<MyUserInfo> list)        {            var ids = list.Select(u => u.ID);            MessageBLL msgbll = new MessageBLL();            var msgs = msgbll.FindByUserIDs(ids);            foreach (var info in list)            {                info.AddExData("Messages", msgs.Where(msg => msg.MyUserID == info.ID).ToList());            }        }    }

  一個DealMsg方法,便來自兩個數據庫的數據連接到一起了,像DealXX的方法可以根據需要要以有多個,分別附加不的數據,再看測試:

    class Program    {        static MyUserBLL userbll = new MyUserBLL();        static void Main(string[] args)        {            F0();            Console.WriteLine();            F1();            Console.WriteLine();            F2();        }        static void F0()        {            var info = userbll.FindOne(2);            Console.WriteLine(info.ToString());        }        static void F1()        {            var list = userbll.Find1();            foreach (var info in list)            {                Console.WriteLine(info.ToString());            }        }        static void F2()        {            var list = userbll.Find2();            foreach (var info in list)            {                Console.WriteLine(info.ToString());                var messages = info.GetExData<List<MessageInfo>>("Messages");                foreach (var msg in messages)                {                    Console.WriteLine("/t{0}", msg.ToString());                }                Console.WriteLine();            }        }    }

至此收工!

很多簡單的東西掌握好了,組合起來也能做一些事件吧!

 下載 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 丹寨县| 长白| 和顺县| 望奎县| 牡丹江市| 永德县| 池州市| 永仁县| 阳山县| 怀仁县| 荆门市| 丹棱县| 微博| 吐鲁番市| 南涧| 岳普湖县| 云浮市| 格尔木市| 新丰县| 乌拉特前旗| 尼木县| 若羌县| 江孜县| 孟津县| 鄂托克旗| 东莞市| 会同县| 大关县| 甘谷县| 万全县| 彩票| 平罗县| 光泽县| 迁安市| 当雄县| 彰化市| 平潭县| 随州市| 电白县| 三门峡市| 夹江县|