我們有相同的場景 - WCF與服務器通信,服務器使用LINQtoSQL。
當從服務器請求對象時,我們使用.ToArray(),因爲客戶端更改列表是「非法的」。 (意思是說,沒有支持「.Add」,「.Remove」等的目的)。
雖然仍然在服務器上,但是,我建議您將其保留爲默認值(不是IEnumerable,而是IQueryable)。這樣,如果您想要根據某些條件進行更多篩選,則需要在SQL端對篩選進行篩選,步驟爲STILL,直至進行評估。
這是非常重要的一點,因爲它意味着取決於你所做的事情,令人難以置信的性能增益或損失。
例:
// This is just an example... imagine this is on the server only. It's the
// basic method that gets the list of clients.
private IEnumerable<Client> GetClients()
{
var result = MyDataContext.Clients;
return result.AsEnumerable();
}
// This method here is actually called by the user...
public Client[] GetClientsForLoggedInUser()
{
var clients = GetClients().Where(client=> client.Owner == currentUser);
return clients.ToArray();
}
你看到發生了什麼呢?「GetClients」方法將強制從數據庫中下載ALL'clients'...然後Where子句將在GetClientsForLoogedInUser方法中進行篩選。
現在,請注意略有變化:
private IQueryable<Client> GetClients()
{
var result = MyDataContext.Clients;
return result.AsQueryable();
}
現在,實際的評價不會發生,直到「.ToArray」叫...和SQL會做的過濾。好多了!
同意ToList立即評估。我們的想法是,在LINQtoSQL中,這很可能會對性能產生影響(特別是如果我們將幾個LINQ表達式鏈接在一起),但是當我們在內存中時,任何性能下降都可以忽略不計 - 人類的一致性更高重要。 – 2008-12-02 16:56:30
除了表現之外,還有顯着差異。特別是,如果有關查詢的任何內容(例如源中的數據)發生更改,則延遲執行會給您一個不同的答案。有時候這就是你想要的,有時候不是。 – 2008-12-02 17:08:33