在我的C#应用程序中延迟加载
我在DAL中有一个方法返回客户列表:在我的C#应用程序中延迟加载,c#,lazy-loading,C#,Lazy Loading,我在DAL中有一个方法返回客户列表: Collection<Customer> FindAllCustomers(); Collection FindAllCustomers(); 客户有以下列:ID、姓名、地址、简历 我需要在我的ASPX表单(show customers.ASPX)中的分页网格中显示它们,其中我将只显示以下列:ID、Name 现在,在我的DAL FindAllCustomers()中,我是否也从SP返回Bio字段(我正在使用读取器填充集合)?生物场可以很大(n
Collection<Customer> FindAllCustomers();
Collection FindAllCustomers();
客户有以下列:ID、姓名、地址、简历
我需要在我的ASPX表单(show customers.ASPX)中的分页网格中显示它们,其中我将只显示以下列:ID、Name
现在,在我的DAL FindAllCustomers()中,我是否也从SP返回Bio字段(我正在使用读取器填充集合)?生物场可以很大(nvarchar(max))。我在考虑延迟加载或只加载所需的字段。但在这种情况下,我需要创建另一个方法,返回包括bio在内的“完整”客户列表,以便第三方应用程序可以通过服务层使用它。这样创建一个方法可以吗:
Collection<Customer> FindAllCustomers(bool loadPartial);
收集最终客户(bool loadPartial);
如果loadPartial=true,则不加载Bio,否则加载它。在这种情况下,因为我不想从SP返回Bio,所以我需要根据bool值在SP中创建2条select语句
我认为在这里使用延迟加载将不起作用,因为这样第三方应用程序就可以访问DAL方法,而第三方应用程序可能也想加载bio
在这种情况下,有没有关于最佳实施模式的建议
谢谢
Vikas如果你的客户名单上从未显示过简历,那么拥有一个精简版就可以了 有几个问题
- 该参数是否仅确定是否加载Bio?将来,当设置为true时,是否会有其他字段不加载
- 如果loadPartial设置为true,则尝试访问Bio会发生什么情况
关键在于确保你选择的任何机制都能适应变化。把自己放在第三方的角度,试着让你的方法达到你所期望的效果。您不希望使用您的类的开发人员必须深入了解这些机制。因此,您可能不需要使用“loadPartial”参数,而只需要使用另一种方法来解析绑定到列表所需的快速、最小数据,并根据需要延迟加载其他字段。我认为这是可以接受的。。。这是你的节目。您只需要确保API是文档化的,并且对其他人有意义 作为补充说明,在存储过程中不一定需要两个存储过程或一个经典的if语句 当
loadPartial==true
时,可以使用case语句NULL
输出字段
Case WHEN @loadPartial = 1 THEN NULL ELSE [bio] END
我认为有两种方法可以针对特定情况进行优化,只要您在方法名称中明确说明。我个人不认为:
Collection<Customer> FindAllCustomers(bool loadPartial);
收集最终客户(bool loadPartial);
这是非常清楚的。开发人员如何知道布尔参数在实践中的实际含义?见问题
把事情弄清楚,一切都会好起来。第三方的事情就是绑定 乍一看,我通常建议您仅正常加载最小的数据,然后根据请求加载完整或更详细的数据(即,触摸属性可能会触发DB调用-可能会轻微滥用属性)或后台处理,具体取决于您所做的工作的性质 通过澄清,惰性属性代码:
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 */
}
}
注意这一点,您不想进行大量的DB调用,但也不想在看到懒惰的东西时造成瓶颈。只有应用程序的性质才能决定这是否合适
我认为您有一个创建布尔标志方法的有效案例(尽管我会默认为轻量级版本),理由是第三方很可能出于与您相同的原因想要轻量级版本
我同意:
Collection<Customer> FindAllCustomers()
{
return this.FindAllCustomers(false);
}
Collection<Customer> FindAllCustomers(bool alldata)
{
/* do work */
}
Collection FindAllCustomers()
{
返回此。FindAllCustomers(false);
}
收集FindAllCustomers(bool alldata)
{
/*工作*/
}
为什么不在Customer类本身的属性中使用延迟加载?为每个属性(Id、名称、Bio)指定一个私有变量。在每个属性的getter中,如果私有变量不是null,则返回它,否则从DAL读入它
对于Bio,如果必须延迟加载它,那么在getter中调用Customer类中另一个名为LazyLoadAdditionalDetails()的方法,并在那里调用相应的存储过程,然后返回私有变量
这样,您可以使代码保持正常,分页视图将只调用ID和名称的getter,并且只有在需要时才从存储过程填充Bio,而无需记住调用延迟加载方法。class CustomerDAO
class CustomerDAO
{
private bool _LoadPartial = true;
public bool LoadPartial
{
get
{
return _LoadPartial;
}
set
{
_LoadPartial = value;
}
}
public Collection<Customer> FindAllCustomers()
{
...
}
}
{
private bool_LoadPartial=true;
公共图书馆
{
得到
{
返回_LoadPartial;
}
设置
{
_LoadPartial=值;
}
}
公共集合FindAllCustomers()
{
...
}
}
这将是另一个选择,尽管我也喜欢安娜卡塔的选择。而不是
Collection<Customer> FindAllCustomers(bool loadPartial);
收集最终客户(bool loadPartial);
我会成功的
Collection<Customer> FindAllCustomers(bool includeBio);
Collection findall客户(bool includeBio);
“loadPartial”不会告诉消费者什么构成“partial”客户。我也同意annakata的观点。在这种情况下,我将使用枚举来更清楚地了解参数的含义
public enum RetrieveCustomerInfo
{
WithBio,
WithoutBio
}
当您调用该方法时:
dao.FindAllCustomers(RetrieveCustomerInfo.WithBio);
我不知道是否更好,但我认为更清楚。1。DAL中传递的bool参数确定是否需要加载其他“非必要大”字段。将来可能会有其他可能不需要的字段。2.如果loadPartial=true,则根本无法访问bio。我理解另一种方法:在访问Bio属性后立即延迟加载。但是,在我看来,这种延迟加载有两种方法:1。在DAL中,让读者读取Bio列,但不要将其加载到Customer属性中。在这种情况下,自r