2014-09-24 92 views
1

這裏的情況:。DateTime.Month上的條款

我正在尋找一個有點大的實體的基本搜索。目前,結果的數量是可管理的,但是我希望在一兩年的使用後有非常多的數據,所以在這裏性能很重要。

我瀏覽的對象有一個DateTime值,我需要能夠輸出所有對象與同一個月,無論年份。有多個可以組合的搜索字段,但其他字段在這裏不會造成問題。

我嘗試這樣做:

if(model.SelectedMonth != null) 
{ 
    contribs = contribs.Where(x => x.Date.Value.Month == model.SelectedMonth); 
} 

model.Contribs = contribs 
    .Skip(NBRESULTSPERPAGE*(model.CurrentPage - 1)) 
    .Take(NBRESULTSPERPAGE) 
    .ToList(); 

到目前爲止,我得到的是「無效的‘其中’狀態的實體構件被調用一個無效的屬性或方法。」我想只是調用ToList(),但它看起來效率不高,實體又相當大。我正在尋找一種乾淨的方式來完成這項工作。

+1

LINQ到什麼地步? LINQ to Entities? LINQ to SQL?其他供應商? – MarcinJuraszek 2014-09-24 21:36:45

+1

我沒有看到問題,你可以發佈內部異常,你得到 – 2014-09-24 21:41:01

+0

LINQ到XRM.Entities(Microsoft Dynamics 2011) – 2014-09-24 21:41:54

回答

1

你說:

對象我瀏覽有一個DateTime值,我需要能夠輸出同月的所有對象,無論一年中

的。 ..

我希望在一兩年的使用後有非常多的數據,所以性能在這裏很重要。

就在那裏,你有一個問題。我知道您使用的是LINQ to CRM,但無論您使用的是什麼技術,此問題實際上都會出現。

潛在的問題是日期和時間存儲在單個字段中。年,月,日,小時,分鐘,秒和小數秒都被打包成一個整數,表示自一段時間以來的單位數。在.NET中DateTime的情況下,自2000年1月1日以來,這是刻度的數目。如果該值存儲在SQL DateTime2字段中,則它是相同的。其他數據類型具有不同的開始日期(時代)和不同的精度。但在所有情況下,內部只有一個數字。

如果您正在尋找月份爲特定年的值,那麼您可以從範圍查詢中獲得不錯的表現。例如,給出所有值> = 2014-01-01和< 2014-02-01。這兩點可以映射回數據庫中的數字表示。如果該字段具有索引,則範圍查詢可以使用該索引。

但是,如果您要查找的值只是月份,那麼您提供的任何查詢都需要數據庫從表格中的每個值中提取該月份。這也被稱爲「表格掃描」,並且沒有索引量會有幫助。

可以有效使用索引的查詢稱爲sargable查詢。但是,您嘗試的查詢是不可測的,因爲它必須評估表中的每個值。

我不知道我有多麼的控制權,你在CRM具有對象及其存儲,但會告訴你什麼,我通常建議人們直接查詢SQL服務器:每月

  • 商店在一個單獨的列中作爲一個整數。有時這可能是根據原始日期時間計算的列,因此您不必直接輸入它。

  • 創建包含此列的索引。

  • 按月查詢時使用此列,以便查詢是可查詢的。

0

這是一個猜測,真的應該是一個評論,但它太多的代碼來格式化評論。如果這沒有幫助,我會刪除答案。

嘗試移動model.SelectedMonth給一個變量,而不是把它的Where條款

var selectedMonth = model.SelectedMonth; 
if(selectedMonth != null) 
{ 
    contribs = contribs.Where(x => x.Date.Value.Month == selectedMonth); 
} 

你可能會做同樣的CurrentPage以及在:

int currentPage = model.CurrentPage; 

model.Contribs = contribs 
    .Skip(NBRESULTSPERPAGE*(currentPage - 1)) 
    .Take(NBRESULTSPERPAGE) 
    .ToList(); 

許多查詢提供比變量更好地工作非關聯對象的屬性。

0

model.SelectedMonth是什麼類型的?

根據您的代碼邏輯,它是可以空的,它似乎可能是一個結構,所以這個工作?

if (model.SelectedMonth.HasValue) 
{ 
    contribs = contribs.Where(x => x.Date.Value.Month == model.SelectedMonth.Value); 
} 
0

您可能需要您的contrib實體,它是通過對日期屬性的實體的創建/更新插件填充創建一個月OptionSet屬性。然後你可以搜索一個特定的月份,而不是搜索日期字段,它搜索一個int字段。這也可以很容易地在高級查找中搜索特定的月份。

Linq to CRM Provider並不是Linq的完整版本。它通常不支持where語句中屬性的任何操作,因爲它必須轉換爲任何QueryExpressions支持。