簡體   English   中英

使用ToList()和使用IList從存儲庫返回IEnumerable

[英]Returning IEnumerable from Repository using ToList() vs using IList

更新3/31/2017

自從這篇文章以來我已經學到了更多的東西,所以想要從存儲庫返回時使用ToList一個重要原因 - 調用ToList將(當使用IQueryable時)在數據庫上執行已翻譯的SQL而不是將記錄拉入內存和然后過濾。 我不相信IEnumerable或IList的隱式轉換會這樣做。


在MSDN網站上的一些教程之后,我在我的應用程序中使用了通用存儲庫層。 此存儲庫層由我的服務層調用,而服務層又由控制器調用。

查看通用存儲庫,獲取數據並通過調用ToList()返回。 但是,該方法的返回類型是IEnumerable ,這意味着服務層必須接受IEnumerable並且在返回控制器之前,它必須再次調用IEnumerable上的ToList()

示例 - 存儲庫:

public IEnumerable<TEntity> Get(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    string includeProperties = "")
{
    IQueryable<TEntity> query = dbSet;

    if (filter != null)
    {
        query = query.Where(filter);
    }

    foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    return orderBy != null ? orderBy(query).ToList() : query.ToList();
}

示例 - 服務層

public IList<DOC> SearchDocuments(string docInfo)
{
    // build the predicate and logic, etc

    // grab all the matching documents with the relationships
    IEnumerable<DOC> documents = _unitOfWork.DocumentRepository.Get(
        predicate,
        p => p.OrderBy(d => d.DocInfo),
        "DocRelationship, DocRelationship.OtherDocTable");

    return documents.ToList();
} 

從我已經完成的閱讀中,似乎最好只向控制器提供它需要的對象List ,而不是IEnumerableIQueryable

因此,我認為最好不要返回IEnumerable來返回IList 我在這里遺漏了什么 - 為什么MSDN團隊選擇IEnumerable進行設計並調用ToList 這會有用嗎? 在我看來,不止一次進行轉換似乎是低效且毫無意義的,特別是在處理大量數據時。

如果不清楚或已經有答案,我提前道歉,但我一直在尋找和閱讀其他帖子IEnumerable vs IQueryable vs IList,但我仍然不明白這個特殊問題。

返回適合您特定情況的最小接口。

通常IEnumerable<T>足夠並且提供更大的靈活性,但是如果你發現自己需要經常使用.ToList() (並且出於正當理由)返回IList<T>甚至List<T>

筆記

  • IEnumerable<T>允許更容易的懶惰評估和單元測試(因為它比IList小 - 所以試着堅持下去。
  • 你的樣本沒有顯示有效的理由來調用.ToList() - 結合IEnumerable<T>直到你知道你究竟在尋找什么甚至可以讓你獲得更好的表現(即如果經過多次檢查你決定只需要一個元素但ToList會強迫你獲取10000)。

你沒事。 現在正在發生的主要事情是repo中的.ToList()實際上正在對數據庫執行查詢。 但是將該列表作為IEnumerable返回,你所做的只是將它裝箱,以便結果是通用且不可更改的。 稍后在unbox上有一些開銷,但由於存儲庫的職責是返回REQUESTED數據,你應該像這樣的imo返回它。

我認為這可能是團隊的想法。 你問過這個數據,所以就在這里。 如果您需要對其進行進一步編輯,則必須再次枚舉它才能對該列表進行任何修改。 這沒什么不對。 實際上,它支持SoC。

通常,我的repos返回IEnumerable,然后如果我的服務層需要返回類似dto或viewmodel的東西,我將使用該IEnum來構建新對象:

var myEnumerable = _uow.MyJunk.Get(j => j.Stuff.Where(a => a.OtherJunk == something);
var myDtos = myEnumerable.Select(obj => new DtoClass { Foo = obj.Foo, Bar = obj.Bar };
return myDtos;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM