我的DAL中有一个方法返回一个客户列表:
Collection<Customer> FindAllCustomers();
客户有以下列:ID,名称,地址,生物
我需要在我的ASPX表单(show-customers.aspx)的分页网格中显示它们,我将只显示这些列:ID,Name
现在,在我的DAL FindAllCustomers()中,我是否也从SP返回Bio字段(我正在使用阅读器填写集合)? Bio字段可以很大(nvarchar(max))。我在考虑延迟加载或只加载必需的字段。但在那种情况下,我需要创建另一种方法,返回一个“完整”的客户列表,包括bio,以便第三方应用程序可以通过服务层使用它。所以可以创建这样的方法:
Collection<Customer> FindAllCustomers(bool loadPartial);
如果loadPartial = true,则不要加载Bio,否则加载它。在这种情况下,因为我不想从SP返回Bio,我需要根据bool值在我的SP中创建2个select语句。
我认为在这里使用延迟加载是行不通的,因为DAL方法可以被第三方应用程序访问,这可能也想加载bio。
有关在这种情况下实施的最佳模式的任何建议吗?
感谢,
维卡斯
答案 0 :(得分: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 */
}
}
小心这一点,你不想进行大量的数据库调用,但是当你看到懒惰的东西时,你也不想创建瓶颈。只有您应用的性质才能决定这是否合适。
我认为你有一个有效的案例来创建布尔标志方法(虽然我会默认为轻量级版本),理由是第三方很可能会因为你做的原因而想要轻量级版本。
我会选择:
Collection<Customer> FindAllCustomers()
{
return this.FindAllCustomers(false);
}
Collection<Customer> FindAllCustomers(bool alldata)
{
/* do work */
}
答案 1 :(得分:3)
在这种情况下,我会使用枚举来更清楚地了解参数的含义。
public enum RetrieveCustomerInfo
{
WithBio,
WithoutBio
}
当你打电话给方法时:
dao.FindAllCustomers(RetrieveCustomerInfo.WithBio);
我不知道它是否更好,但我认为它更清楚。
答案 2 :(得分:1)
如果您的客户列表从未显示过bio,那么使用简化版本就可以了。
一些问题......
关键是确保您选择的任何机制都能适应变化。把自己置于第三方的角度,并尝试让你的方法做你期望的。您不希望使用您的类的开发人员必须深入了解这些机制。因此,您可以使用不同的方法来解析绑定到列表所需的快速,最小化数据,并根据需要延迟加载其他字段,而不是“loadPartial”参数。
答案 3 :(得分:1)
我认为这是可以接受的...这是你的计划。您只是想确保API已记录在案并对其他人有意义。
作为旁注,您不一定需要在存储过程中使用两个存储过程或经典if语句。
NULL
时,您可以在loadPartial == true
字段中使用案例陈述。
Case WHEN @loadPartial = 1 THEN NULL ELSE [bio] END
答案 4 :(得分:1)
我认为只要在方法名称中明确说明,就可以为特定情况优化两种方法。我个人认为:
Collection<Customer> FindAllCustomers(bool loadPartial);
很清楚。开发人员如何知道该布尔参数在实践中的实际意义?请参阅boolean parameters — do they smell?问题。
说清楚,一切都很好。
答案 5 :(得分:1)
为什么不在Customer Class本身的属性中使用延迟加载?给每个属性(Id,Name,Bio)一个私有变量。在每个属性的getter中,如果私有变量不为null,则返回它,否则从DAL中读取它。
说到Bio,如果你不得不加载它,那么在你的getter中你调用Customer Class中另一个名为LazyLoadAdditionalDetails()的方法并在那里调用相应的sprocs,然后返回你的私有变量。
通过这种方式,您可以保持代码正常,并且您的分页视图只会调用ID和名称的getter,并且只有在需要时才会从sproc中填充您的Bio,而无需记住调用延迟加载方法
答案 6 :(得分:0)
class CustomerDAO
{
private bool _LoadPartial = true;
public bool LoadPartial
{
get
{
return _LoadPartial;
}
set
{
_LoadPartial = value;
}
}
public Collection<Customer> FindAllCustomers()
{
...
}
}
将是另一种选择,虽然我也喜欢annakata的一个。
答案 7 :(得分:0)
而不是
Collection<Customer> FindAllCustomers(bool loadPartial);
我做到了
Collection<Customer> FindAllCustomers(bool includeBio);
“loadPartial”不会告诉消费者什么构成“部分”客户。我也同意annakata的观点。