2

我的 DAL 中有一个方法返回客户列表:

Collection<Customer> FindAllCustomers();

客户有这些列:ID、姓名、地址、简历

我需要在我的 ASPX 表单 (show-customers.aspx) 的分页网格中显示它们,我将只显示这些列:ID、名称

现在,在我的 DAL FindAllCustomers() 中,我是否也从 SP 返回 Bio 字段(我正在使用阅读器填写集合)?Bio 字段可以很大 (nvarchar(max))。我正在考虑延迟加载或仅加载必填字段。但是在那种情况下,我需要创建另一种方法,该方法返回一个“完整”的客户列表,包括 bio,以便 3rd 方应用程序可以通过服务层使用它。那么创建这样的方法是否可以:

Collection<Customer> FindAllCustomers(bool loadPartial);

如果 loadPartial = true,则不加载 Bio,否则加载它。在这种情况下,由于我不想从 SP 返回 Bio,我需要根据 bool 值在我的 SP 中创建 2 个选择语句。

我认为在这里使用延迟加载是行不通的,因为 DAL 方法可以被第 3 方应用程序访问,它可能也想加载 bio。

关于在这种情况下实施的最佳模式有什么建议吗?

谢谢,

维卡斯

4

8 回答 8

3

第 3 方的事情是绑定。

乍一看,我通常建议您仅正常加载最少的数据,然后按要求加载完整或更多详细信息(即触摸属性可能会触发数据库调用 - 那里可能会轻微滥用属性)或后台进程,取决于你正在做的事情的性质。

通过澄清的方式懒惰的财产代码:

class Customer
{
  private string _lazydata = null;

  public string LazyData
  {
    get
    {
      if (this._lazydata==null)
      {
        LazyPopulate();
      }
      return this._lazydata;
    }
  }

  private void LazyPopulate()
  {
    /* fetch data and set lazy fields */
  }
}

请注意这一点,您不想进行大量的数据库调用,但也不想在看到一些懒惰的东西时造成瓶颈。只有您的应用程序的性质才能决定这是否合适。

我认为您有一个有效的案例来创建布尔标志方法(尽管我会默认为轻量级版本),因为第 3 方很可能会出于与您相同的原因想要轻量级版本。

我会去:

Collection<Customer> FindAllCustomers()
{
  return this.FindAllCustomers(false);
}

Collection<Customer> FindAllCustomers(bool alldata)
{
  /* do work */
}
于 2009-08-11T20:53:48.170 回答
3

在这种情况下,我会使用枚举来更清楚地了解参数的含义。

public enum RetrieveCustomerInfo
{
   WithBio,
   WithoutBio
}

当您调用该方法时:

dao.FindAllCustomers(RetrieveCustomerInfo.WithBio);

我不知道它是否更好,但我认为它更清楚。

于 2010-01-19T20:51:20.813 回答
1

如果您的客户列表从不显示简历,那么精简版本就可以了。

几个问题...

  • 该参数是否仅确定是否加载了 Bio?将来,您是否会有其他字段在设置为 true 时不加载?
  • 如果 loadPartial 设置为 true,我尝试访问 Bio 会发生什么?

关键是确保您选择的任何机制都能适应变化。将自己置于第 3 方的角度,并尝试使您的方法达到您的预期。您不希望使用您的类的开发人员必须深入了解这些机制。因此,也许您只需使用不同的方法来解决绑定到列表所需的快速、最少数据并根据需要延迟加载其他字段,而不是“loadPartial”参数。

于 2009-08-11T20:45:45.380 回答
1

我认为这是可以接受的......这是你的程序。您只想确保 API 已记录并对其他人有意义。

作为旁注,您不一定需要两个存储过程或存储过程中的经典 if 语句。

您可以使用 case 语句来NULL输出字段 when loadPartial == true

Case WHEN @loadPartial = 1 THEN NULL ELSE [bio] END
于 2009-08-11T20:47:29.073 回答
1

我认为只要在方法名称中明确说明,就可以针对特定情况优化两种方法。个人不认为:

Collection<Customer> FindAllCustomers(bool loadPartial);

很清楚。开发人员如何知道该布尔参数在实践中的实际含义?查看布尔参数——它们有味道吗?问题。

说清楚,一切都很好。

于 2009-08-11T20:49:34.530 回答
1

为什么不在客户类本身的属性中使用延迟加载?给每个属性(Id、Name、Bio)一个私有变量。在每个属性的 getter 中,如果私有变量不为 null,则返回它,否则从 DAL 中读取它。

当涉及到 Bio 时,如果你必须延迟加载它,那么在你的 getter 中你调用 Customer 类中的另一个方法 LazyLoadAdditionalDetails() 并在那里调用适当的存储过程,然后返回你的私有变量。

这样你就可以让你的代码保持正常,你的分页视图只会调用 ID 和 Name 的 getter,并且你的 Bio 只会在需要时从存储过程中填充,而你不必记住调用延迟加载方法。

于 2009-08-11T20:54:32.320 回答
0
class CustomerDAO
{
   private bool _LoadPartial = true;
   public bool LoadPartial
   {
      get
      {
         return _LoadPartial;
      }

      set
      {
         _LoadPartial = value;
      }
   }


   public Collection<Customer> FindAllCustomers()
   {
      ...
   }
}

将是另一种选择,虽然我也喜欢 anakata 的。

于 2009-08-11T20:55:18.887 回答
0

代替

Collection<Customer> FindAllCustomers(bool loadPartial);

我会成功的

Collection<Customer> FindAllCustomers(bool includeBio);

“loadPartial”不会告诉消费者什么是“部分”客户。我也同意 anakata 的观点。

于 2009-08-11T21:00:06.053 回答