2013-04-24 54 views
6

目前,我有這個自動取500行:有條件地將。取()

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).Take(500); 

我想使採取()有條件的,是這樣的:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate); 
if (condition) 
    orderQuery = orderQuery.Take(500); 

是這可能嗎?

編輯:
編譯器說

「無法隱式轉換類型 'System.Linq.IQueryable' 到 'System.Linq.IOrderedQueryable'。」

+0

什麼了你的編譯器告訴你? – 2013-04-24 21:15:55

回答

8

添加「AsQueryable已」,使類型排隊:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).AsQueryable(); 
if (condition) 
    orderQuery = orderQuery.Take(500); 
+0

我用這個來維護var的使用。感謝大家。 – chrismat 2013-04-24 22:37:42

6

這可能嗎?

是的。你的代碼應該像書面一樣工作。你只需要消除var。假設你的類型是Order。你會使用:

IQueryable<Order> orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate); 
if (condition) 
    orderQuery = orderQuery.Take(500); 
+0

實際上,我不認爲這是因爲在第一條語句中'var'推斷爲'IOrderedEnumerable <>',而在第二條語句中'Take'產生'IEnumerable <>'。 – 2013-04-24 21:15:35

+1

@AnthonyPegram True - 修正。 – 2013-04-24 21:37:22

10

在LINQ到對象中,var將推斷到IOrderedEnumerable<T>,其中T是你的對象的類型。 Take()將產生一個IEnumerable<T>,所以你的代碼行將不被允許。 (IOrderedEnumerable比IEnumerable指定的更多,您需要以較少指定的方式鍵入您的查詢。)並且,正如註釋所指出的那樣,對於處理IQueryable<T>的提供者也是如此,該提供者本身可以表示爲少指定IEnumerable<T>

要使其工作,請將您的查詢明確地鍵入您需要的較小指定類型,IEnumerable<T>IQueryable<T>,然後您可以應用您的條件Take

IEnumerable<YourType> orderedQuery = ... 
if (condition) 
    orderedQuery = orderedQuery.Take(n); 
+1

+1在LINQ to SQL/entities/NHibernate中用'IQueryable'替換'IEnumerable',情況也是如此。 – 2013-04-24 21:37:57

-1

我要做的就是添加排序在末尾,以避免將它們轉換

var orderQuery = subsetTable.Where(pred); 

if (condition) 
    orderQuery = orderQuery.Take(500); 

orderQuery = orderQuery.OrderByDescending(o => o.CreationDate); 
+3

這改變了行爲,因爲你只排序前500個元素,而不是前500個排序元素。 – 2013-04-24 21:48:18

+0

不,當您執行查詢時將應用'.Take(500)'。在'.List();'例如 – 2013-04-24 21:49:10

+0

是的 - 當你查詢時執行Take,但Take被解釋爲表示獲取結果,然後排序,原始排序的位置,然後取得(在服務器上)。 – 2013-04-24 22:14:08