自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

.NET平臺下一個小Web開發(fā)項目總結(jié)

開發(fā) 后端
本文是關(guān)于.NET平臺下,一個小Web開發(fā)項目的總結(jié)。雖然很基礎(chǔ),但是對大家的項目管理工作還是有一定幫助的。

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

一、代碼生成器確實好用

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

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

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

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

例如,假設(shè)Album、News、Knowledge這三個類都具有某些相同的屬性(ID,Title,AccountId,ViewCount,CreateTime,UpdateTime,等),在代碼生成器生成的文件之外,另建一個目錄,放一個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)類型的,可在編譯器檢查錯誤的。

二、分頁

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

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

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

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

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

(b)存儲過程使用前需要添加進(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集成在一起了,取***頁時,使用的是Top,以優(yōu)化性能。同時,也省掉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)是***頁時,去調(diào)用 GetDataCount 方法,獲得count參數(shù),這個參數(shù)直接傳遞給第二頁,第三頁……的url,避免查看第二頁第三頁時,重復(fù)獲得count,影響性能。

三、封裝和復(fù)用

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

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

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

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

(3)獲得全部熱點的對象;獲得N天內(nèi)熱點的對象;以上可以按不同的排序方式排序;獲得審核通過的對象,獲得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等編輯的操作項,分別代表是否鎖定,是否熱門,是否推薦和是否精華。News和Knowledge還有個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   

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

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

然后,寫一個公用的控件類,以復(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 = "點擊";   
  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ā)還是太累。一個月坐下來還沒做其它項目三五天賺的錢多,并且技術(shù)支持比其它類型項目難得多。做一個Web項目后悔一次,今后,盡量不做了,除非價格很高或自己用。

原文標(biāo)題:最近一個小Web開發(fā)項目的總結(jié)

鏈接:http://www.cnblogs.com/xiaotie/archive/2010/04/28/1723364.html

【編輯推薦】

  1. 添加設(shè)置ASP.NET Web時出現(xiàn)問題
  2. 實戰(zhàn)ASP.NET大規(guī)模網(wǎng)站架構(gòu):Web加速器
  3. Visual Studio 2010升級Web開發(fā)功能
  4. 淺談C#實現(xiàn)Web代理服務(wù)器的幾大步驟
  5. 詳解ASP.NET MVC 2自定義驗證
     
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2016-03-01 13:48:36

MVVMios快速開發(fā)

2014-09-05 09:45:46

2011-10-31 10:17:47

開發(fā)平臺

2012-03-29 09:22:56

云計算私有云開發(fā)

2015-10-29 09:35:12

BAT趨勢數(shù)據(jù)

2011-05-18 10:18:10

2020-11-15 23:23:21

JavaScriptAPI開發(fā)

2013-09-22 11:19:06

云平臺移動游戲

2014-06-17 10:57:09

2019-03-19 19:19:19

Facebook微信轉(zhuǎn)型

2019-01-15 10:02:06

Kubernetes開源工具微服務(wù)

2009-03-28 09:22:12

MID移動OS

2022-02-13 15:49:15

WebAssemblKubernetes容器

2015-08-03 14:06:44

2023-12-07 09:44:29

2014-11-12 10:26:25

Bootstrap

2013-01-17 10:09:50

JavaSpring

2021-08-11 18:23:08

數(shù)據(jù)平臺IT

2011-03-17 15:01:11

Oracle

2023-12-11 09:20:15

點贊
收藏

51CTO技術(shù)棧公眾號