2013-05-02 102 views
2

請參閱以下內容:擴展方法在LINQ的聲明

public Content GetContentByPageTitle(string pageTitle) 
{ 
    return _db.Contents.FirstOrDefault(
      x => hnUrlHelper.UrlSafe(x.PageTitle).Equals(pageTitle) 
     ); 
} 


public class hnUrlHelper 
{ 
    public static string UrlSafe(string value) 
    { 
     if (!string.IsNullOrEmpty(value)) 
     { 
      value = value.Replace("Š", "s"); 

      value = value.Trim().ToLower(); 

      value = value.Replace(" ", "-"); 

      value = Regex.Replace(value, @"[^A-Za-z0-9-_]", ""); 

      return value.Trim().ToLower(); 
     } 
     return string.Empty; 
    } 
} 

Server Error in '/' Application. LINQ to Entities does not recognize the method 'System.String UrlSafe(System.String)' method, and this method cannot be translated into a store expression.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NotSupportedException: LINQ to Entities does not recognize the method 'System.String UrlSafe(System.String)' method, and this method cannot be translated into a store expression.

Source Error:

我試圖找出Linq的語句中UrlSafe方法。這顯示如下錯誤。 有沒有人知道如何解決這個問題?

回答

0

你可能大部分都使用擴展方法,但我認爲你不能爲正則表達式部分做些什麼。

我能做的最好的就是這樣的。

public static T FirstOrDefaultUrlSafe<T>(this IQueryable<T> queryable, Expression<Func<T, string>> propertyExpression, string pageTitle) 
     { 
      var parameter = propertyExpression.Parameters[0]; 
      var propertyName = (propertyExpression.Body as MemberExpression).Member.Name; 
      Expression body = parameter; 
      body = Expression.Property(body, propertyName); 
      body = Expression.Call(body, "Replace", null, new[] { Expression.Constant("Š"), Expression.Constant("s") }); 
      body = Expression.Call(body, "ToLower", null); 
      body = Expression.Call(body, "Trim", null); 
      body = Expression.Call(body, "Replace", null, new[] { Expression.Constant(" "), Expression.Constant("-") }); 
      body = Expression.Equal(body, Expression.Constant(pageTitle)); 
      var lambda = Expression.Lambda<Func<T, bool>>(body, new[] { parameter }); 
      return queryable.FirstOrDefault(lambda); 
     } 

使用你的情況:

return _db.Contents.FirstOrDefaultUrlSafe(x => x.PageTitle, pageTitle) 
+0

讚賞。非常感謝。它完美的工作。 – Tun 2013-05-02 14:13:25

0

異常告訴你,你的方法不能被翻譯成SQL。在這種情況下,有無法修復它,因爲該方法使用Regex,它不能被轉換爲SQL。

一種常見的方式來解決這些異常將有一個返回值表達式的屬性或方法:只要你使用ReplaceToLower

_db.Contents.FirstOrDefault(EqualsUrl(pageTitle)) 

Expression<Func<Content,bool>> EqualsUrl(string url) 
{ 
    return c => c.PageTitle.Replace("Š", "s") == url; 
} 

稱爲像這樣,Trim和類似的方法,EF 可以翻譯成SQL你沒事。但是,如上所述,Regex是這裏的表演。