【问题标题】:Extension method at Linq statementLinq 语句中的扩展方法
【发布时间】:2013-05-02 11:54:18
【问题描述】:

请看下面:

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;
    }
}

“/”应用程序中的服务器错误。 LINQ to Entities 无法识别方法 'System.String UrlSafe(System.String)' 方法,并且无法翻译此方法 成商店表达式。

描述:未处理的异常 在执行当前 Web 请求期间发生。请 查看堆栈跟踪以获取有关错误和位置的更多信息 它起源于代码。

异常详情: System.NotSupportedException:LINQ to Entities 无法识别 method 'System.String UrlSafe(System.String)' 方法,以及这个方法 不能翻译成商店表达式。

来源错误:

我正在尝试在 Linq 语句中解决 UrlSafe 方法。这显示如下错误。 有没有人知道如何证明这个可以工作?

【问题讨论】:

    标签: asp.net-mvc-3 linq entity-framework-4


    【解决方案1】:

    您可以在大多数情况下使用扩展方法,但我认为您不能为正则表达式部分做点什么。

    我能做到的最好的就是这样。

    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)
    

    【讨论】:

      【解决方案2】:

      异常告诉你你的方法不能被翻译成 SQL。在这种情况下,没有办法修复它,因为该方法使用的Regex 也无法转换为 SQL。

      修复此类异常的常用方法是使用返回表达式的属性或方法:

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

      这样称呼:

      _db.Contents.FirstOrDefault(EqualsUrl(pageTitle))
      

      只要您使用ReplaceToLowerTrim 以及 EF 可以 转换为 SQL 的类似方法,就可以了。但是,如前所述,Regex 是这里的亮点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-24
        • 1970-01-01
        • 2013-09-24
        • 1970-01-01
        • 2021-04-29
        • 2011-11-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多