LayIM項目之基礎資料擷取代碼最佳化,Dapper取代ADO.NET

來源:互聯網
上載者:User

標籤:採訪   對象   個數   思路   基礎   sed   .text   detail   ati   

前言

  最近在開發LayIM融雲版,也在進行項目重構,現在在看之前的代碼,簡直不敢直視。不過不知道以後看現在的代碼是不是也是糟糕的一批。LayIM有個介面,一般接觸過的開發人員都不會生疏,就是init介面。介面返回的資料大概就是醬紫的:

 1 { 2     "code": 0, 3     "msg": "", 4     "data": { 5         "mine": { 6             "username": "紙飛機", 7             "id": "100000", 8             "status": "online", 9             "sign": "在深邃的編碼世界,做一枚輕盈的紙飛機",10             "avatar": "/images/default.jpg"11         },12         "friend": [13             {14                 "groupname": "前端碼屌",15                 "id": 1,16                 "online": 2,17                 "list": [18                     {19                         "username": "賢心",20                         "id": "100001",21                         "avatar": "/images/default.jpg",22                         "sign": "這些都是測試資料,實際使用請嚴格按照該格式返回"23                     },24                     {25                         "username": "Z_子晴",26                         "id": "108101",27                         "avatar": "/images/default.jpg",28                         "sign": "微電商達人"29                     }30                 ]31             },32             {33                 "groupname": "網紅",34                 "id": 2,35                 "online": 3,36                 "list": [37                     {38                         "username": "羅玉鳳",39                         "id": "121286",40                         "avatar": "/images/default.jpg",41                         "sign": "在自己實力不濟的時候,不要去相信什麼媒體和記者。他們不是善良的人,有時候候他們的採訪對當事人而言就是陷阱"42                     },43                     {44                         "username": "長澤梓Azusa",45                         "id": "100001222",46                         "sign": "我是日本女藝人長澤あずさ",47                         "avatar": "/images/default.jpg"48                     }49                 ]50             }51         ],52         "group": [53             {54                 "groupname": "前端群",55                 "id": "101",56                 "avatar": "/images/default.jpg"57             },58             {59                 "groupname": "Fly社區官方群",60                 "id": "102",61                 "avatar": "/images/default.jpg"62             }63         ]64     }65 }
LayIM init介面資料

  總之,裡面嵌套了很多關係,比如,我的好友分組和好友的關係,還有其他的一些資料,其實,仔細分析一下,也就會各個擊破了。今天的重點不是這個資料,而是關於擷取這段資料代碼的重構。

之前的代碼

  之前用的ADO.NET直接讀取的DataSet,然後進行資料處理,主要麻煩的是,還需要手動寫DataTable轉Model的過程,還要處理關係,比較繁瑣,並且需要知道其中的欄位。(當然,dapper也需要對應)。先看一下之前的代碼,總之這段代碼就是很古老的一種形式。

 private  BaseListResult ToBaseListResult(DataSet ds)        {            if (ds.Tables.Count > 0)            {                if (ds.Tables[0].Rows.Count ==0) {                    return new BaseListResult();                }                //目前使用者的資訊                var rowMine = ds.Tables[0].Rows[0];                //使用者組資訊                var rowFriendDetails = ds.Tables[2].Rows.Cast<DataRow>().Select(x => new GroupUserEntity                {                    id = x["uid"].ToInt(),                    avatar = x["avatar"].ToString(),                    groupid = x["gid"].ToInt(),                    remarkname = x["remarkname"].ToString(),                    username = x["nickname"].ToString(),                    sign = x["sign"].ToString(),                    //status之前的欄位是為空白的,現在我們把他的線上狀態加上,IsOnline方法接收一個userid參數,從Redis緩衝中讀取該使用者是否線上並返回                    status = LayIMCache.Instance.IsOnline(x["uid"].ToInt()) ? "online" : "hide"                }).OrderByDescending(x => x.status);//這裡要根據使用者是否線上這個欄位排序,保證線上使用者都在好友名單最上邊                //使用者組資訊,執行分組                var friend = ds.Tables[1].Rows.Cast<DataRow>().Select(x => new FriendGroupEntity                {                    id = x["id"].ToInt(),                    groupname = x["name"].ToString(),                    online = 0,                    list = rowFriendDetails.Where(f => f.groupid == x["id"].ToInt())                });                //群組資訊                var group = ds.Tables[3].Rows.Cast<DataRow>().Select(x => new GroupEntity                {                    id = x["id"].ToInt(),                    groupname = x["name"].ToString(),                    avatar = x["avatar"].ToString(),                    groupdesc = x["groupdesc"].ToString()                });                //使用者皮膚,第一個是預設正在使用的                List<string> skin = ds.Tables[4].Rows.Cast<DataRow>().Select(x => x[0].ToString()).ToList();                BaseListResult result = new BaseListResult                {                    mine = new UserEntity                    {                        id = rowMine["id"].ToInt(),                        avatar = rowMine["avatar"].ToString(),                        sign = rowMine["sign"].ToString(),                        username = rowMine["nickname"].ToString(),                        status = "online"                    },                    friend = friend,                    group = group,                    skin = skin                };                return result;            }            return null;        }

  下面,我們改用Dapper試試。重構過程先不談,看一下重構後的代碼處理:

  public BaseListResult Handle(SqlMapper.GridReader reader)        {            var result = new BaseListResult();            //使用者本人資料            result.mine = reader.ReadFirst<UserEntity>();            //處理friend邏輯 start            var friend = reader.Read<FriendGroupEntity>();            var groupUsers = reader.Read<GroupUserEntity>();            friend.ToList().ForEach(f =>            {                //每一組的人分配給各個組                f.list = groupUsers?.Where(x => x.groupid == f.id);            });            result.friend = friend;            //處理friend邏輯 end            //讀取使用者所在群            result.group = reader.Read<GroupEntity>();            return result;        }

  Dapper相較於ADO.NET比起來,就清爽多了,首先,處理GridReader,然後直接調用Read<T>方法,直接將表值轉換為Model,不過Model的值需要對應。然後轉換完之後,在進行一步邏輯處理,就是將相應的使用者跟好友分組的id對應上。最後一個返回,這樣看起來就清爽了許多,也不用處理的很麻煩。下文記錄一下我的開發思路。

代碼思路

  首先要解決一個問題就是,解耦的問題,Dapper中有一個方法就是 QueryMultiple ,他是返回一個GridReader 對象,然後進行處理。那麼這個GridReader對象又必須在串連開著的時候使用,所以,不能直接返回然後關閉對象,所以,可以採用介面的形式,將處理方法提出去,或者,我剛才恰好想到的就是用Func<SqlMapper.GridReader,TResult> 方式來處理結果。My Code如下:

 public static T QueryMultiple<T>(string sql, object param,CommandType commandType = CommandType.Text, IMultipleHandler<T> handler=null)        {            using (var connection = getConnection())            {                using (var multi = connection.QueryMultiple(sql, param,commandType: commandType))                {                    if (handler == null) {                        return default(T);                    }                    return handler.Handle(multi);                }            }        }

  其中的IMultipleHandler 中就一個方法,Handle方法,參數為GridReader。然後返回 T類型的結果。所以上文中,我的調用方式很簡單了,就是傳入相應的處理類就可以了。

 public class UserBaseListHandler : IMultipleHandler<BaseListResult>

  其實我剛才突然想到,或許用Func更方便。不用再定義類繼承介面了。此篇,Over,重構代碼確實是有意思的事情,後續我會將各種體會做總結,如果能和讀者產生共鳴那是最好不過的了。

LayIM項目之基礎資料擷取代碼最佳化,Dapper取代ADO.NET

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.