簡體   English   中英

.Wate子句上的DateTime.Month

[英].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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM