2

设计关于将 UI 与数据访问分开的 ascx 用户控件的“最佳实践”是什么?我的用户控件应该像在我的项目中那样使用 3 层架构,还是可以从用户控件中进行数据访问?

4

5 回答 5

2

您永远不应该从用户控件访问数据库。您应该创建一个用于访问数据库的类,并且应用程序中的所有内容都应该使用该类。基本上,类中的方法将是存储过程调用的包装器,但应用程序(以及用户控件)看到的只是具有所需参数的方法。从应用程序的角度来看,不了解数据库。这允许您在不更改应用程序的情况下更改数据库。

此链接可能会帮助您:

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

于 2009-12-23T16:22:02.473 回答
1

现在无论项目多么简单或复杂,至少都应该分为表示层、业务层和数据层。在任何给定时间,三者中的任何一个都可以改变而不会影响其他人。

用户控件是表示层的一部分,它应该向业务层提供数据和用户操作,业务层反过来解释数据和这些操作以做出决策。如有必要,业务层将调用数据层。反过来,数据层将处理与数据库/源文件的所有通信。

将三者分开并保持分开并不难。

于 2009-12-23T16:38:52.747 回答
0

我肯定会建议从某种业务层访问数据。UI 永远不应该直接访问数据库。

  • 如果您的访问规则发生变化怎么办?
  • 如果您的存储发生变化怎么办?
  • 您能否确保每个 UI 控件都能够执行业务规则?
  • 等等
于 2009-12-23T16:15:48.903 回答
0

这就是我在我的项目中所拥有的。

1.)应用程序.基础设施

  • 所有业务对象的基类、业务对象集合、数据访问类以及我的自定义属性和实用程序作为扩展方法、通用验证框架。这决定了我最终的 .net 应用程序的整体行为组织。

2.) Application.DataModel

  • 数据库的类型化数据集。
  • TableAdapters 扩展为包含我可能需要的事务和其他功能。

3.)应用程序.数据访问

  • 数据访问类。
  • 使用基础类型化数据集查询数据库操作的实际位置。

4.) Application.DomainObjects

  • 业务对象和业务对象集合。
  • 枚举。

5.) Application.BusinessLayer

  • 提供可从表示层访问的管理器类。
  • HttpHandler。
  • 我自己的 Page 基类。
  • 更多的东西去这里..

6.) Application.WebClientApplication.WindowsClient

  • 我的表示层
  • 从 Application.BusinessLayer 和 Application.BusinessObjects 获取引用。

Application.BusinessObjects 在整个应用程序中使用,并在需要时跨越所有层 [Application.DataModel 和 Application.Infrastructure 除外]

我所有的查询都只定义了 Application.DataModel。

Application.DataAccess 作为任何数据访问操作的一部分返回或获取业务对象。业务对象是在反射属性的帮助下创建的。每个业务对象都标有到数据库中目标表的属性映射,并且业务对象内的属性标有映射到相应数据库表中目标列的属性。

我的验证框架允许我在指定的 ValidationAttribute 的帮助下验证每个字段。

我的框架大量使用属性来自动化大多数繁琐的任务,如映射和验证。我还可以将新功能作为框架中的新方面。

在我的应用程序中,示例业务对象看起来像这样。

用户.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)
    {
    }
}
于 2009-12-23T16:25:21.383 回答
0

您至少需要一个 2 层解决方案:数据,然后是其他一切。对于更复杂的项目,您需要将其他所有内容抽象为表示、逻辑和数据。数据也可以分为数据访问层和数据模型层。

于 2009-12-23T17:08:01.153 回答