2017-12-27 996 views
2

Linq實體無法使用DateTime.ToString(string)方法嗎?使用下面的方法拋出異常LINQ to Entities does not recognize the method 'System.DateTime ToString(System.String)' method, and this method cannot be translated into a store expression.,這是預期的,因爲它不能轉換爲SQL。Linq to Entities實現DateTime.ToString(字符串)

protected override bool TryGetEntitiesByKey(IEnumerable<string> keys, out IEnumerable<Trade> entities) 
{ 
    return this.TryLoadBase(x => keys.ToList().Contains(x.date.ToString("yyyyMMdd"), out entities); 
} 

在通用供應商,這是使用FUNC過濾從DB結果的代碼,如下。

protected virtual bool TryLoadBase(Expression<Func<TEntity, bool>> filter, out IEnumerable<TEntity> entities) 
{ 
    bool loaded = true; 
    try 
    { 
    using (var db = this.dbContext) 
    { 
     entities = db.Set<TEntity>().Where(filter).ToList(); 
    } 
    } 
    catch (Exception ex) // Exception caught here 
    { 
    loaded = false; 
    entities = new List<TEntity>(); 
    } 
    return loaded; 
} 

後得到的例外前面提到的,我試過這個取代date.ToString(「年月日」):

SqlFunctions.StringConvert((double)notional.date.Year).Trim() + 
SqlFunctions.Replicate("0", 2 - SqlFunctions.StringConvert((double)notional.date.Month).Trim().Length) + SqlFunctions.StringConvert((double)notional.date.Month).Trim() + 
SqlFunctions.Replicate("0", 2 - SqlFunctions.StringConvert((double)notional.date.Day).Trim().Length) + SqlFunctions.StringConvert((double)notional.date.Day).Trim() 

雖然這個工作,它具有否則你得到的是直列關於LINQ to Entities不能識別該方法的相同消息。這意味着閱讀起來很困難,不能被其他任何東西重複使用。

環顧四周後,我發現這個問題:(Reusable Calculations For LINQ Projections In Entity Framework),但我不願意包括任何外部軟件包只是爲了解決這個問題。

還有Entity Framework 4/Linq: How to convert from DateTime to string in a query?的答案,但據我所知在接受的答案中使用AsEnumerable()將意味着枚舉數據庫集到內存中,由於內存限制,我無法做到這一點。而且我無法得到第二個答案能夠正常工作,並且它會再次遭受上面SqlFunctions混亂的問題。

如果這是不可能的,是否有人能夠提供一個清潔的替代SqlFunctions塊?

+3

將鍵轉換爲日期而不是日期轉換爲字符串可能會更好,因爲您要過濾的列是日期類型。 – Evk

+0

請注意,捕獲_any_異常並僅僅返回一個空列表可能不是一個好設計 - 您不能分辨是否存在潛在錯誤(或更糟糕的是,該錯誤是什麼),或者如果您的篩選器沒有返回任何對象。 –

+0

將日期轉換爲字符串以供機器使用時,指定'CultureInfo'就像'CultureInfo.Invariant'是明智的。否則,你可能會得到一個令人驚訝的結果。舉一個具體的例子,如果你的代碼執行的用戶的文化是泰國的,那麼2017年的(UTC)年將被格式化爲2560. –

回答

1

您正在要求提供者將呼叫DateTime.ToString(format)轉換爲不受支持的SQL。您可能還需要使用EntityFunctions.TruncateTime比較只有日期部分(因爲這就是字符串比較會做):

你要麼需要解析的關鍵日期/時間對象或傳遞一個IEnumerable<DateTime>代替:

protected override bool TryGetEntitiesByKey(IEnumerable<string> keys, out IEnumerable<Trade> entities) 
{ 
    var keyDates = keys.Select(s => DateTime.ParseExact("yyyyMMdd")).ToList(); 
    return this.TryLoadBase(x => keyDates.Contains(EntityFunctions.TruncateTime(x.date)), out entities); 
}