2013-05-02 101 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是这里的表演。