清单VS IEnumerable的私人,延迟加载特性 [英] List vs IEnumerable in private, lazy-loaded property

查看:114
本文介绍了清单VS IEnumerable的私人,延迟加载特性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个公共属性(AllCustomers),它是由私有财产的延迟加载的支持。

I have a public property (AllCustomers), which is backed by a private property for lazy loading.

据我了解,公共财产应的IEnumerable(<一个href=\"http://stackoverflow.com/questions/2697783/what-does-program-to-interfaces-not-implementations-mean\">\"program到接口,而不是实现)。

I understand that the public property should be IEnumerable ("program to interfaces, not implementations").

不过,我可以看到两种方式来构建私有财产。

However, I can see two ways to build the private property.

第一个选项,私人清单 -

First option, with private List-

private List<Customer> _AllCustomers;
public IEnumerable<Customer> AllCustomers
{
    get
    {
        if (_AllCustomers == null)
        {
            _AllCustomers = DAL.GetAllCustomers().ToList(); 
        }
        return _AllCustomers;
    }
}

第二个选择,与私人的IEnumerable -

Second option, with private IEnumerable-

private IEnumerable<Customer> _AllCustomers;
public IEnumerable<Customer> AllCustomers
{
    get
    {
        if (_AllCustomers == null)
        {
            _AllCustomers = DAL.GetAllCustomers(); 
        }
        return _AllCustomers;
    }
}

我认为第一个选项出现更正确,因为它会一次击中数据库和存储结果,而第二个将导致多个数据库访问。

I think the first option appears more correct, as it will hit the database once and store the results, whereas the second will result in multiple database hits.

我的问题是 -


  • 我在我的分析是正确的?

  • 什么是不同方法的含义是什么?

  • 有没有时间第二个选项是preferred?

  • 有没有更好的,更地道的方式来恩$ P $的PSS
    第二个选项?

推荐答案

有这里涉及到懒惰的几个层次。一个是的IEnumerable 实现固有的惰性,另一种是懒惰的实现你自己添加到您的财产。

There are several levels of "laziness" involved here. One is the inherent laziness of IEnumerable implementations, the other is the lazy implementation you add yourself to your property.

您第一次执行会打一次数据库,在第一时间 AllCustomers 进行访问。它会构造查询在 GetAllCustomers 并执行它,当你调用了ToList ,本地存储的结果。

Your first implementation will hit the database once, the first time AllCustomers is accessed. It will construct the query in GetAllCustomers and perform it when you call ToList, storing the results locally.

你的第二个实施将的访问数据库只有一次(假设你的LINQ实现是半路出家)。然而,这将是的之后的比第一个方案 - 甚至称你的 AllCustomer 属性将只返回一个的IQueryable ,当 AllCustomers 实际上是访问或列举了才会执行。这可能会立即之后,或不 - 这是一个懒惰的实现。同样,假设你的LINQ提供程序是不是太傻了,遍历整个集合仍将只命中了一次DB

Your second implementation will also hit the database only once (assuming your LINQ implementation is halfway decent). However, this will be later than in the first scenario - even calling your AllCustomer property will only return an IQueryable, which will only be performed when AllCustomers is actually accessed or enumerated. This might be immediately after, or not - it's a lazier implementation. Again, assuming your LINQ provider isn't too stupid, iterating over the entire collection will still only hit the DB once.

为什么要选择第一个选项呢?由于(再次,取决于实现),遍历 AllCustomers 两次的可能击中了两次DB。 ReSharper的,够方便,警告我们,当我们有一个的IEnumerable 的可能的多个枚举。在本地将其存储列表将确保我们保持一个缓存本地副本。为了确保这是前$ P $在code明确pssed,考虑露出的 IReadOnlyList 代替的IEnumerable

Why should you choose the first option anyway? Because (again, depending on the implementation), iterating over AllCustomers twice might hit the DB twice. Resharper, conveniently enough, warns us when we have a possible multiple enumeration of an IEnumerable. Storing it in a local List will ensure we keep a cached local copy. To make sure this is expressed explicitly in the code, consider exposing an IReadOnlyList instead of an IEnumerable.

这篇关于清单VS IEnumerable的私人,延迟加载特性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆