国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
.NET平臺(tái)下一個(gè)小Web開發(fā)項(xiàng)目總結(jié) - 51CTO.COM
    本文是關(guān)于.NET平臺(tái)下,一個(gè)小Web開發(fā)項(xiàng)目的總結(jié)。雖然很基礎(chǔ),但是對大家的項(xiàng)目管理工作還是有一定幫助的。

    一直以來很少寫Web開發(fā)的具體代碼,以前是專門有人寫這些,我只管管就行了。后來呢,也很少做Web類型項(xiàng)目了,最近有兩個(gè)項(xiàng)目,牽扯到Web開發(fā),而現(xiàn)在一個(gè)人單干,也找不到人來寫這些了,只得自己憋手蹩腳的摸索。下面是這段時(shí)間的摸索總結(jié)。

    一、代碼生成器確實(shí)好用

    以前是很反代碼生成器的,但真的使用過后覺得很好用——簡單、直接且控制力強(qiáng)。我用的是園子里李天平(http://ltp.cnblogs.com/)的動(dòng)軟代碼生成器。在此,先感謝一下。不過,在感謝李天平之前,我必須先感謝一下郭嘉。

    動(dòng)軟的好處是簡單、直接、開源。針對我的應(yīng)用,我做了以下改進(jìn):

    (1)Image的處理問題。代碼生成器生成的操作Image部分的代碼有小問題,不能插入全部的Image對象,這個(gè)手動(dòng)修改了下。

    (2)生成的代碼沒有 partial 關(guān)鍵字,不方便擴(kuò)展。我修改成產(chǎn)生的所有類都是partial類。這樣做有什么好處呢?就是對于每個(gè)類,你可以在不修改生成的源文件的情況下,申明某個(gè)類實(shí)現(xiàn)了某些接口,以對代碼進(jìn)行復(fù)用。

    例如,假設(shè)Album、News、Knowledge這三個(gè)類都具有某些相同的屬性(ID,Title,AccountId,ViewCount,CreateTime,UpdateTime,等),在代碼生成器生成的文件之外,另建一個(gè)目錄,放一個(gè)Interface.cs的文件:

            
    1.  public interface IContent   
    2.  {   
    3.      Guid Id { getset; }   
    4.      String Title { getset; }   
    5.      String AccountId { get; }   
    6.      String Caption { get; }   
    7.      Int32 ViewCount { getset; }   
    8.      DateTime CreateTime { getset; }   
    9.      DateTime UpdateTime { getset; }   
    10. }   
    11.  
    12. public interface IContentVoteable : IContent   
    13. {   
    14.     Int32 VoteCount { getset; }   
    15. }   
    16.  
    17. public partial class Album : IContent   
    18. {   
    19.     public String Caption { get { return "相冊"; } }   
    20. }   
    21.  
    22. public partial class News : IContent   
    23. {   
    24.     public String Caption { get { return "資訊"; } }   
    25. }   
    26.  
    27. public partial class Knowledge : IContent   
    28. {   
    29.     public String Caption { get { return "手記"; } }   
    30. }  

    這樣就可以對生成的類進(jìn)行類型“指派”,可用于泛型代碼來簡化編程。并且這種“指派”是強(qiáng)類型的,可在編譯器檢查錯(cuò)誤的。

    二、分頁

    這是一個(gè)老話題了。以前我直接用GridView和ObjectDataSource,結(jié)果是當(dāng)需求變化了痛苦不堪。比如,客戶要求用 VS2005 ……

    本著拿來主義的原則,拿來了園子里張子陽(http://www.cnblogs.com/jimmyzhang/)的分頁代碼。感謝張子陽。在感謝張子陽之前,再感謝一下郭嘉。

    具體的開發(fā)過程中做了一些思考,做出了以下改變:

    (1)沒有使用分頁存儲(chǔ)過程,而是在C#代碼中進(jìn)行封裝,納入我的基礎(chǔ)庫里面。這樣做的理由是:

    (a)分頁代碼比較簡單,分頁的數(shù)據(jù)庫操作比較耗時(shí),作為存儲(chǔ)過程對性能提高不明顯;

    (b)存儲(chǔ)過程使用前需要添加進(jìn)數(shù)據(jù)庫,而在C#端使用則可以省略這一步驟。

    (c)方便調(diào)用、修改和封裝。以下是我寫的C#端的數(shù)據(jù)庫分頁代碼:

    代碼 

            
    1. public static DataTable GetPagerData(String tableName, String returnColumns, String where, 
    2. String orderColumnName, Boolean orderDesc, String keyColumnName, Int32 pageSize, Int32 pageIndex, params SqlParameter[] whereParams)   
    3.  {   
    4.      if (pageIndex == 1)   
    5.     {   
    6.          return GetTopData(pageSize, tableName, returnColumns, where, orderColumnName, orderDesc, RemoveNull(whereParams));   
    7.      }   
    8.      else   
    9.     {   
    10.          String sql = String.Format("select top {0} {1} from {2} where {3} and {6} not in 
    11. ( select top {7} {6} from {2} where {3} order by {4} {5} )  order by {4} {5}", pageSize, returnColumns, tableName, where, 
    12. orderColumnName, orderDesc == true ? "desc" : String.Empty, keyColumnName, pageSize * (pageIndex - 1));   
    13.         return Query(sql, RemoveNull(whereParams)).Tables[0];   
    14.     }   
    15. }    
    16. public static Int32 GetDataCount(String tableName, String where, params SqlParameter[] whereParams)   
    17. {   
    18.     String sql = String.Format("select count(*) from {0} where {1}" , tableName, where);   
    19.     Int32 result = (Int32)GetSingle(sql, RemoveNull(whereParams));   
    20.     return result;   
    21. }    
    22. public static DataTable GetTopData(Int32 top, String tableName, String returnColumns, String where, 
    23. String orderColumnName, Boolean orderDesc, params SqlParameter[] whereParams)   
    24. {   
    25.     String sql = String.Format("select top {0} {1} from {2} where {3} order by {4} {5}", top, returnColumns, 
    26. tableName, where, orderColumnName, orderDesc == true ? "desc" : String.Empty);   
    27.     return Query(sql, whereParams).Tables[0];   
    28. }   
    29. private static SqlParameter[] RemoveNull(SqlParameter[] whereParams)   
    30. {   
    31.     List<SqlParameter> list = new List<SqlParameter>();   
    32.     foreach (SqlParameter sq in whereParams)   
    33.     {   
    34.         if (sq != null) list.Add(sq);   
    35.     }   
    36.     return list.ToArray();   

    在這段代碼中,我直接將分頁和Top集成在一起了,取第一頁時(shí),使用的是Top,以優(yōu)化性能。同時(shí),也省掉Top調(diào)用。這樣做的好處,在下面能體現(xiàn)出來。

    (2)對于分頁部分的代碼,我默認(rèn)進(jìn)行一下處理:

    (a)url的page參數(shù)指現(xiàn)在的pageIndex;

    (b)url的count參數(shù)指查詢結(jié)果的總數(shù)量;

    “count” 和 “page ”也可以指定為其它字符串。當(dāng)是第一頁時(shí),去調(diào)用 GetDataCount 方法,獲得count參數(shù),這個(gè)參數(shù)直接傳遞給第二頁,第三頁……的url,避免查看第二頁第三頁時(shí),重復(fù)獲得count,影響性能。

    三、封裝和復(fù)用

    通過上面的處理,就很方便對代碼進(jìn)行封裝和復(fù)用了。

    還是以上面的Album,News和Knowledge來說,這三個(gè),編輯都可以從后臺(tái)加精、推薦、設(shè)為熱點(diǎn)、鎖定、審核通過與否等操作。如何用最簡單的代碼來實(shí)現(xiàn)前臺(tái)和后臺(tái)所需要的以下需求呢:

    (1)獲得全部加精的對象;獲得N天內(nèi)加精的對象;以上可以按不同的排序方式排序;獲得審核通過的對象,獲得N天內(nèi)審核通過的對象;

    (2)獲得全部推薦的對象;獲得N天內(nèi)推薦的對象;以上可以按不同的排序方式排序;獲得審核通過的對象,獲得N天內(nèi)審核通過的對象;

    (3)獲得全部熱點(diǎn)的對象;獲得N天內(nèi)熱點(diǎn)的對象;以上可以按不同的排序方式排序;獲得審核通過的對象,獲得N天內(nèi)審核通過的對象;

    (4)獲得最新的對象;獲得N天內(nèi)審核通過的對象;

    (5)獲得瀏覽量最多的對象;獲得N天內(nèi)瀏覽量最多的對象;獲得審核通過的對象,獲得N天內(nèi)審核通過的對象;

    (6)以上檢索可指定賬號,也可以是全體賬號。

    ……

    這里假設(shè)Album,News和Knowledge在數(shù)據(jù)庫里相關(guān)列的列名都是一致的,EnableStatus代表審核通過與否,0代表待審核,1代表審核通過,-1代表審核未通過;IsLocked,IsHot,IsChoiced,IsMarked等編輯的操作項(xiàng),分別代表是否鎖定,是否熱門,是否推薦和是否精華。News和Knowledge還有個(gè)CategoryId的列,代表所屬類別。

    以News為例子,代碼為:

    代碼 

            
    1. public partial class NewsService : Orc.HairFashion.BLL.News   
    2.  {   
    3.      public static NewsService Instance;   
    4.    
    5.      static NewsService()   
    6.      {   
    7.          Instance = new NewsService();   
    8.      }   
    9.    
    10.     public static void UpdateColumnStatus(ICollection<Guid> ids, String columName, int status)   
    11.     {   
    12.         DbHelper.UpdateColumnStatus(ids, "News", columName, status);   
    13.     }   
    14.     #region 分頁查找    
    15.     protected static DataTable GetPagerData(String where, String orderColumnName, Int32 pageSize, Int32 pageIndex, params SqlParameter[] whereParams)   
    16.     {   
    17.         return DbHelper.GetPagerData("News""*", where, orderColumnName, true"Id", pageSize, pageIndex, whereParams);   
    18.     }    
    19.     protected static Int32 GetDataCount(String where, params SqlParameter[] whereParams)   
    20.     {   
    21.         return DbHelper.GetDataCount("News", where, whereParams);   
    22.     }    
    23.     public static List<News> SelectData(String accountId, String mark, String mode, Int32 categoryId, Int32 inDays, String orderColumnName, Int32 pageSize, Int32 pageIndex)   
    24.     {   
    25.         DataTable table = GetPagerData(" 1=1 " + Util.BuildSqlByMark(mark) + Util.BuildSqlByMode(mode) + Util.BuildSqlByCategoryId(categoryId) + Util.BuildSqlByCreateInDays(inDays) + Util.BuildSqlByAccountId(accountId), orderColumnName, pageSize, pageIndex, Util.BuildSqlParameterByAccountId(accountId));   
    26.         return NewsService.Instance.DataTableToList(table);   
    27.     }   
    28.     public static Int32 SelectCount(String accountId, String mark, String mode, Int32 categoryId, Int32 inDays)   
    29.     {   
    30.         return GetDataCount(" 1=1 " + Util.BuildSqlByMark(mark) + Util.BuildSqlByMode(mode) + Util.BuildSqlByCategoryId(categoryId) + Util.BuildSqlByCreateInDays(inDays) + Util.BuildSqlByAccountId(accountId), Util.BuildSqlParameterByAccountId(accountId));   
    31.     }   
    32.     #endregion   

    就只用這簡簡單單的代碼就可以了。這里各個(gè)查詢選項(xiàng)是“正交”的。accountId 為 null或Empty,則檢索全部。mark代表編輯的查詢類型,是全部,還是精華還是熱門還是最新……,實(shí)際上這里最好是傳入enum。mode代表審核狀態(tài),最好使用enum。這兩處沒用enum是歷史遺留問題。categoryId代表類別id,如果為負(fù)數(shù)則檢索全部的類別,inDays代表檢索多少天內(nèi)的數(shù)據(jù),負(fù)數(shù)代表全部,orderColumnName 是排序列,我默認(rèn)全部desc了,pageSize 是頁大小,pageIndex是頁序號。

    這部分代碼是在我動(dòng)軟代碼生成器的源代碼,使它生成帶partial的類之前修改的。如果現(xiàn)在寫,使用泛型的話,可以將上面的代碼進(jìn)一步簡化。

    然后,寫一個(gè)公用的控件類,以復(fù)用共有代碼:

            
    1. BaseListControl   
    2.   public abstract class BaseListControl : System.Web.UI.UserControl   
    3.   {   
    4.       private Boolean m_showPager = false;   
    5.       private Int32 m_pageSize = 12;   
    6.       private Boolean m_orderByVoteCount = true;   
    7.       private Int32 m_inDays = 7;   
    8.       private String m_caption = "";   
    9.       private String m_viewCaption = "點(diǎn)擊";   
    10.       private String m_voteCaption = "票數(shù)";   
    11.      private String m_orderBy = "CreateTime";   
    12.      private String m_mark = "";   
    13.      private String m_mode = "";   
    14.    
    15.      public Int32 Count = 0;   
    16.      public Boolean ShowPager { get { return m_showPager; } set { m_showPager = value; } }   
    17.      public Int32 PageSize { get { return m_pageSize; } set { m_pageSize = value; } }   
    18.      public String Caption { get { return m_caption; } set { m_caption = value; } }   
    19.      public String ViewCaption { get { return m_viewCaption; } set { m_viewCaption = value; } }   
    20.      public String VoteCaption { get { return m_voteCaption; } set { m_voteCaption = value; } }   
    21.      public String OrderBy { get { return m_orderBy; } set { m_orderBy = value; } }   
    22.      public String Mark { get { return m_mark; } set { m_mark = value; } }   
    23.      public String Mode { get { return m_mode; } set { m_mode = value; } }   
    24.      public Int32 InDays { get { return m_inDays; } set { m_inDays = value; } }   
    25.      protected void Page_Load(object sender, EventArgs e)   
    26.      {   
    27.          if (Page.IsPostBack == false)   
    28.          {   
    29.              OnPageLoad();   
    30.              InitPager();   
    31.              BindData();   
    32.          }   
    33.      }   
    34.    
    35.      protected abstract PagerControl GetPager();   
    36.      protected abstract Int32 GetResultCount();   
    37.      protected virtual void OnPageLoad()   
    38.      {   
    39.      }   
    40.       protected void InitPager()   
    41.      {   
    42.          PagerControl pager = GetPager();   
    43.          if (ShowPager == false)   
    44.          {   
    45.              if(pager!=null)   
    46.                  pager.Visible = false;   
    47.          }   
    48.          else   
    49.          {   
    50.              Int32 count = PageUtil.GetCurrentCount(this.Page);   
    51.              if (count < 0) count = GetResultCount();   
    52.    
    53.              if(pager!=null)   
    54.                  pager.UrlManager = new Orc.Util.AspDotNet.DefaultUrlManager(count, PageSize, "page""count");   
    55.          }   
    56.      }   
    57.    
    58.      protected void BindData()   
    59.      {   
    60.          Int32 page = PageUtil.GetCurrentPage(this.Page);   
    61.          if (page < 1) page = 1;   
    62.          BindData(page);   
    63.      }   
    64.    
    65.      protected abstract void BindData(Int32 page);   
    66.  } 

    然后是具體的控件:

            
    1. Controls_NewsList   
    2.   public partial class Controls_NewsList : BaseListControl   
    3.   {   
    4.       private Int32 m_categoryId = -1;   
    5.       public Int32 CategoryId   
    6.       {   
    7.           get { return m_categoryId; }   
    8.           set { m_categoryId = value; }   
    9.       }   
    10.     
    11.      protected override Orc.Util.AspDotNet.PagerControl GetPager()   
    12.      {   
    13.         return this.pager;   
    14.      }   
    15.    
    16.      protected override int GetResultCount()   
    17.      {   
    18.          return NewsService.SelectCount(nullthis.Mark, this.Mode, this.CategoryId, this.InDays);   
    19.      }    
    20.      protected override void BindData(int page)   
    21.      {   
    22.          this.rpList.DataSource = NewsService.SelectData
    23. (nullthis.Mark, this.Mode, this.CategoryId, this.InDays, this.OrderBy, this.PageSize, page);   
    24.          this.rpList.DataBind();   
    25.      }   
    26.  } 

    這樣一封裝就超級好用,可以顯示pager也可以不顯示,可以用在分頁里,也可以用在欄目的首頁,且代碼量幾乎降低到最低,而性能幾乎提高到最高,還可以根據(jù)各種參數(shù)進(jìn)行緩存。

    四、抱怨

    盡管使用了這些技巧,Web開發(fā)還是太累。一個(gè)月坐下來還沒做其它項(xiàng)目三五天賺的錢多,并且技術(shù)支持比其它類型項(xiàng)目難得多。做一個(gè)Web項(xiàng)目后悔一次,今后,盡量不做了,除非價(jià)格很高或自己用。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用pager-taglib.jar實(shí)現(xiàn)的分頁技術(shù)
常用公共代碼二之分頁代碼的實(shí)現(xiàn)
靜態(tài)塊與非靜態(tài)塊的區(qū)別
蛙蛙推薦:ASP.NET MVC學(xué)習(xí)筆記
.Net 面試 .Net面試題集
JAVA異常設(shè)計(jì)原則 - Java綜合 - Java - JavaEye論壇
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服