2009-12-23 70 views
2

什麼是設計用於將UI與數據訪問分離的ascx用戶控件的「最佳實踐」?我的用戶控件是否應該在我的項目中使用3層架構,或者我可以在用戶控件中執行數據訪問嗎?從ascx用戶控件中的數據訪問中分離UI

+1

http://www.codethinked.com/post/2009/12/22/The-Static-Spider-Web-Pattern.aspx – 2009-12-23 17:03:02

回答

2

您不應該從用戶控件訪問數據庫。您應該創建一個用於訪問數據庫的類,並且應用程序中的所有內容都應該使用該類。基本上,類中的方法將圍繞您的存儲過程調用進行包裝,但應用程序(以及用戶控件)看到的所有內容都是具有所需參數的方法。從應用程序的角度來看,沒有關於數據庫的知識。這使您可以在不更改應用程序的情況下更改數據庫。

此鏈接可以幫助你:

http://www.simple-talk.com/dotnet/.net-framework/.net-application-architecture-the-data-access-layer/

+0

好的鏈接文章。好評。謝謝。 – 2009-12-30 17:44:07

0

我肯定會建議從某種業務層訪問數據。 UI永遠不應該直接訪問數據庫。

  • 如果您的訪問規則發生了變化,該怎麼辦?
  • 如果您的存儲設備發生了變化,該怎麼辦?
  • 您能確保每個UI控件都能夠執行業務規則嗎?
0

這是我在我的項目。

1)Application.Infrastructure

  • 基類所有的BusinessObjects,業務內容對象集合,數據訪問類和我的自定義屬性和公用事業擴展方法,通用驗證框架。這決定了我的最終.net應用程序的整體行爲組織。

2.)Application.DataModel

  • 類型化數據集的數據庫。
  • TableAdapters擴展到合併交易和我可能需要的其他功能。

3.)Application.DataAccess

  • 數據訪問類。
  • 使用底層的Typed Dataset查詢數據庫操作的實際位置。

4)Application.DomainObjects

  • 業務對象和業務對象的集合。
  • 枚舉。

5.)Application.BusinessLayer

  • 提供從表示層訪問管理器類。
  • HttpHandlers。
  • 我自己的頁面基類。
  • 更多的事情在這裏..

6)Application.WebClientApplication.WindowsClient

  • 我的表現層
  • 從Application.BusinessLayer和應用程序需要引用。的BusinessObjects。

Application.BusinessObjects跨應用程序使用,他們在所有層行進時neeeded [除Application.DataModel和Application.Infrastructure]

我所有的查詢僅定義Application.DataModel。

Application.DataAccess返回或將Business對象作爲任何數據訪問操作的一部分。業務對象是在反射屬性的幫助下創建的。每個業務對象都標有映射到數據庫中目標表的屬性,業務對象內的屬性標有映射到相應數據庫表中的目標列的屬性。

我的驗證框架讓我可以在指定的ValidationAttribute的幫助下驗證每個字段。

我的框架大量使用屬性來自動化大部分繁瑣的任務,如映射和驗證。我也可以將新功能作爲框架中的新功能。

示例業務對象在我的應用程序中看起來像這樣。

User.cs

[TableMapping("Users")] 
public class User : EntityBase 
{ 
    #region Constructor(s) 
    public AppUser() 
    { 
     BookCollection = new BookCollection(); 
    } 
    #endregion 

    #region Properties 

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute 

    private System.Int32 _UserId; 

    private System.String _FirstName; 
    private System.String _LastName; 
    private System.String _UserName; 
    private System.Boolean _IsActive; 

    [DataFieldMapping("UserID")] 
    [DataObjectFieldAttribute(true, true, false)] 
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")] 
    public override int Id 
    { 
     get 
     { 
      return _UserId; 
     } 
     set 
     { 
      _UserId = value; 
     } 
    } 

    [DataFieldMapping("UserName")] 
    [Searchable] 
    [NotNullOrEmpty(Message = "Username Is Required.")] 
    public string UserName 
    { 
     get 
     { 
      return _UserName; 
     } 
     set 
     { 
      _UserName = value; 
     } 
    } 

    [DataFieldMapping("FirstName")] 
    [Searchable] 
    public string FirstName 
    { 
     get 
     { 
      return _FirstName; 
     } 
     set 
     { 
      _FirstName = value; 
     } 
    } 

    [DataFieldMapping("LastName")] 
    [Searchable] 
    public string LastName 
    { 
     get 
     { 
      return _LastName; 
     } 
     set 
     { 
      _LastName = value; 
     } 
    } 

    [DataFieldMapping("IsActive")] 
    public bool IsActive 
    { 
     get 
     { 
      return _IsActive; 
     } 
     set 
     { 
      _IsActive = value; 
     } 
    } 

    #region One-To-Many Mappings 
    public BookCollection Books { get; set; } 

    #endregion 

    #region Derived Properties 
    public string FullName { get { return this.FirstName + " " + this.LastName; } } 

    #endregion 

    #endregion 

    public override bool Validate() 
    { 
     bool baseValid = base.Validate(); 
     bool localValid = Books.Validate(); 
     return baseValid && localValid; 
    } 
} 

BookCollection.cs

/// <summary> 
/// The BookCollection class is designed to work with lists of instances of Book. 
/// </summary> 
public class BookCollection : EntityCollectionBase<Book> 
{ 
    /// <summary> 
    /// Initializes a new instance of the BookCollection class. 
    /// </summary> 
    public BookCollection() 
    { 
    } 

    /// <summary> 
    /// Initializes a new instance of the BookCollection class. 
    /// </summary> 
    public BookCollection (IList<Book> initialList) 
     : base(initialList) 
    { 
    } 
} 
+0

非常好的答案,但他並不是要求整個項目,而是要求一個用戶控制。 – 2009-12-23 16:51:00

+0

同意,但這可能讓他有辦法看到更大的圖片。 – 2009-12-24 03:27:52

+0

你的回答很好地描述瞭如何映射數據。我缺少的是你在項目中使用的* .ASCX用戶控件之一 - 這就是問題所在。 類似[這篇文章](http://blogs.msdn.com/b/davidebb/archive/2005/10/31/turning-an-ascx-user-control-into-a-redistributable-custom-control。 aspx) - 好吧,也許是你的答案和那篇文章的組合。 – Matt 2014-02-24 14:40:55

1

現在無論簡單還是複雜的項目,起碼,都應該被分爲表示層,業務層和數據層。在任何時候,三者中的任何一個都可以改變而不影響其他人。

用戶控件是表示層的一部分,它應該將數據和用戶動作提供給業務層,而業務層又將數據和那些動作解釋爲做出決策。如有必要,業務層將調用數據層。數據層反過來將處理與數據庫/源文件的所有通信。

將三者分開並保持分開並不難。

0

您至少需要2層解決方案:數據,然後是其他所有內容。對於更復雜的項目,您需要將其他所有內容都抽象出來,然後將其抽象爲演示文稿,邏輯和數據。數據也可以分爲數據訪問和數據模型層。