爲什麼這麼多列表/ ToLists? IEnumerable/IQueryable出了什麼問題?
var eventi = (from Evento ae in new Eventi()
select ae);
if (strNome != "")
{
eventi = eventi.Where(e => e.Titolo.ToLower().Contains(strNome.ToLower()) && e.Titolo != "");
}
if (strComune != "")
{
eventi = eventi.Where(e => e.Comune != null && e.IDComune == strComune);
}
if (strMesi != "")
{
eventi = eventi.Where(e => MesiSelezionati.Contains(DateTime.Parse(e.DataEvento).Month.ToString()));
}
// if you do need a list, then do so right at the end
var results = eventi.ToList();
編輯:爲了澄清一些原則Caesay
Caesay,感謝您抽出寶貴的時間來測試執行確認延遲加載按預期工作;很多榮譽!
我想解釋一下爲什麼要與你的上述做法是在運行時而你是在編譯時優化優化評論不同意。
上面的方法是,由於缺少更好的描述,打算使用的方法。這是因爲對甚至的分配正確地將表達式附加到IEnumerable/IQueryable的源。
只有某些提供商(如Linq to Entities)支持您的方法,這些提供商希望將Func(Of T, TResult)傳遞給它們的Select,Where等擴展。許多提供者(如實體框架和Linq to Sql提供者)提供IQueryable,它們實現了IEnumerable。然而,這裏的區別在於,IQueryable的Select,Where等,期望您通過Expression(Of Func(Of T, TResult))。
在這些情況下,您的代碼不會像預期的那樣行爲(或至少如我所料),因爲Expression不支持多行lambda,因爲編譯器會正確解釋我的語句並將它們編譯爲Expression>。
作爲一個簡單的例子:
public void Test<T1, T2>(System.Linq.Expressions.Expression<Func<T1, T2>> arg)
{
throw new NotImplementedException();
}
public void Test()
{
Test((string x) => x.ToLower());
Test((string x) =>
{
return x.ToLower();
});
}
在上述例子中,第一個表達式是絕對優良。第二,這是鬆散的基礎上你的榜樣,將失敗,異常:
A lambda expression with a statement body cannot be converted to an expression tree
編譯器可以識別您的語句作爲Func鍵它知道被支持的IEnumerable。結果將是對數據庫的查詢不會包含任何Where表達式,並返回整個數據源。一旦數據源在內存中,它就會應用您的IEnumerable Where子句。就個人而言,我更喜歡將這些東西傳遞給數據庫,這樣我就不會浪費帶寬返回比我需要的數據更多的數據,並且我可以利用數據源功能來過濾可能(並且很大程度上在Sql Server的情況)比在內存中更好。
我希望這是有道理的,對您有用嗎?
當你投了集合列出你基本上獲取iqueryable列表。如果您不直接投射,則需要提供結果,您應該重新執行查詢 – cpoDesign