[英]How to filter datetime.Month from mongo collection by aggregation?
[英].Where clause on 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();
到目前為止,我得到的只是“無效的'where'條件。實體成員正在調用無效的屬性或方法。” 我想到的只是調用ToList(),但它似乎並不是很有效,實體又很大。 我正在尋找一種清潔的方法來完成這項工作。
你說:
我正在瀏覽的對象具有DateTime值,並且我需要能夠輸出具有相同月份的所有對象,而與年份無關
...
我預計一兩年的使用后會有大量的數據,因此性能在這里很重要。
就在那兒,你有問題。 我了解您正在使用LINQ to CRM ,但是無論您使用什么技術,實際上都會出現此問題。
潛在的問題是日期和時間存儲在單個字段中。 年,月,日,小時,分鍾,秒和小數秒都打包成一個整數,代表某個時間以來的單位數。 對於.NET中的DateTime
,這是自1/1/0001起的滴答數。 如果該值存儲在SQL DateTime2
字段中,則是同一回事。 其他數據類型具有不同的開始日期(時期)和不同的精度。 但是在所有情況下,內部只有一個數字。
如果要搜索特定年份一個月內的值,則可以從范圍查詢中獲得不錯的性能。 例如,給出所有值> = 2014-01-01和<2014-02-01。 這兩個點可以映射回數據庫中的數字表示形式。 如果該字段具有索引,則范圍查詢可以使用該索引。
但是,如果您要查找的值僅一個月 ,則您提供的任何查詢都將要求數據庫從表中的每個值中提取該月。 這也稱為“表掃描”,沒有任何索引量會有所幫助。
能有效地使用索引的查詢被稱作一可優化搜索查詢。 但是,您要查詢的查詢不可保留,因為它必須評估表中的每個值。
我不知道您對CRM中的對象及其存儲有多少控制,但是我將告訴您通常建議人們直接查詢SQL Server的內容:
將月份作為一個整數存儲在單獨的列中。 有時,這可以是基於原始日期時間的計算列,因此您不必直接輸入它。
創建一個包含此列的索引。
按月份查詢時,請使用此列,以便查詢可保存。
這是一個猜測,實際上應該是一個注釋,但是太多的代碼無法在注釋中很好地格式化。 如果沒有幫助,我將刪除答案。
嘗試將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();
與不相關對象的屬性相比,許多查詢提供程序在使用變量時效果更好。
model.SelectedMonth
是什么類型?
根據您的代碼邏輯,它是可為空的,並且看起來它可能是一個結構,這行得通嗎?
if (model.SelectedMonth.HasValue)
{
contribs = contribs.Where(x => x.Date.Value.Month == model.SelectedMonth.Value);
}
您可能需要在contrib實體上創建一個Month OptionSet屬性,該屬性通過為日期屬性創建/更新該實體的插件來填充。 然后,您可以按特定月份進行搜索,而不是搜索“日期”字段,而是搜索一個int字段。 這也將使在高級查找中搜索特定月份變得容易。
Linq to CRM Provider不是Linq的完整版本。 它通常不支持對where語句中的屬性進行任何形式的操作,因為必須將其轉換為QueryExpressions支持的格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.