3

它可能是一个简单的 3 层问题。我只是想确保我们为此使用最佳实践,而且我对这些结构还不是很熟悉。

我们有 3 层:

  • GUI:用于表示层的 ASP.NET(第一个平台)
  • BAL:业务层将在 C# 中处理网络服务器上的逻辑,所以我们都可以将它用于 webforms/MVC + webservices
  • DAL:数据层中的 LINQ to SQL,返回 BusinessObjects 而不是 LINQ。
  • DB:SQL 将是 Microsoft SQL-server/Express(尚未决定)。

让我们考虑一下我们有一个 [Persons] 数据库的设置。他们都可以有多个 [Address] 并且我们有所有 [PostalCode] 和相应城市名称等的完整列表。

交易是我们从其他表格中加入了很多细节。

{关系}/[表格]

  • [Person]:1 --- N:{PersonAddress}:M --- 1:[Address]
  • [地址]:N --- 1:[邮编]

现在我们要为 Person 构建 DAL。PersonBO 的外观应该如何以及连接何时发生?获取所有城市名称和可能的地址公关是业务层问题吗?人?或者 DAL 是否应该在将 PersonBO 返回给 BAL 之前完成所有这些?

Class PersonBO 
{
    public int ID {get;set;}
    public string Name {get;set;}
    public List<AddressBO> {get;set;} // Question #1
} 

// Q1:我们在返回 PersonBO 之前检索对象吗?它应该是一个数组吗?或者这对于 n 层/3 层来说是完全错误的吗?

Class AddressBO 
{
    public int ID {get;set;}
    public string StreetName {get;set;}
    public int PostalCode {get;set;} // Question #2
} 

// Q2:我们是进行查找还是留下 PostalCode 以供以后查找?

谁能解释以什么顺序拉哪些对象?建设性的批评是非常受欢迎的。:o)

4

1 回答 1

2

你是在重新发明轮子;ORM 已经为您解决了大部分问题,您会发现自己做起来有点棘手。

像 Linq to SQL、Entity Framework 和 NHibernate 这样的 ORM 执行此操作的方式是一种称为关联延迟加载的技术(可以选择用急切加载覆盖)。

当您拉起 aPerson时,它不会加载,Address直到您特别要求它,此时会发生另一个到数据库的往返(延迟加载)。您还可以基于每个查询指定要Address每个人加载(急切加载)。

从某种意义上说,对于这个问题,你基本上是在问你是否应该为 执行惰性加载或急切加载,AddressBO答案PersonBO是:都不行。没有一种单一的方法可以普遍有效。 默认情况下,您可能应该延迟加载,这样您就不会进行大量不必要的连接;为了实现这一点,您必须PersonBO使用延迟加载机制来构建您的机制,以维护对 DAL 的一些引用。但是您仍然希望拥有预先加载的选项,您需要将其构建到您的“业务访问”逻辑中。

另一种选择是,如果您需要返回具有从许多不同表填充的特定属性的高度自定义的数据集,则根本不返回 a PersonBO,而是使用数据传输对象(DTO)。如果您实现默认的延迟加载机制,您有时可以将其替换为急切加载版本。


仅供参考,数据访问框架中的延迟加载器通常使用关联本身的加载逻辑构建:

public class PersonBO
{
    public int ID { get; set; }
    public string Name { get; set; }
    public IList<AddressBO> Addresses { get; set; }
}

这只是一个 POCO,魔法发生在实际的列表实现中:

// NOT A PRODUCTION-READY IMPLEMENTATION - DO NOT USE

internal class LazyLoadList<T> : IList<T>
{
    private IQueryable<T> query;
    private List<T> items;

    public LazyLoadList(IQueryable<T> query)
    {
        if (query == null)
            throw new ArgumentNullException("query");
        this.query = query;
    }

    private void Materialize()
    {
        if (items == null)
            items = query.ToList();
    }

    public void Add(T item)
    {
        Materialize();
        items.Add(item);
    }

    // Etc.
}

(这显然不是生产级的,只是为了演示该技术;您从查询开始,直到您必须实现实际列表。)

于 2010-06-05T14:15:07.140 回答