代码之家  ›  专栏  ›  技术社区  ›  Russell Steen

林肯SqlMethods.就像失败

  •  7
  • Russell Steen  · 技术社区  · 14 年前

    我在听提示 here ,尝试利用在枚举器触发之前不会创建sql的语句。但是我在下面的代码中得到了以下错误。不使用linq2i'。在Linq2entities中有没有一种方法可以做到这一点?

    类布尔型方法(字符串系统, 字符串系统)'不能在客户端上使用;它仅用于转换为SQL。

                query = db.MyTables.Where(x => astringvar.Contains(x.Field1));
    
                if (!String.IsNullOrEmpty(typeFilter))
                {
                    if (typeFilter.Contains('*'))
                    {
                        typeFilter = typeFilter.Replace('*', '%');
                        query = query.Where(x=> SqlMethods.Like(x.Type, typeFilter));
                    }
                    else
                    {
                        query  = query.Where(x => x.Type == typeFilter);
                    }
                }
    

    4 回复  |  直到 14 年前
        1
  •  11
  •   Thomas Levesque    9 年前

    我不知道如何使实体框架使用“real”LIKE运算符,但是一个可能的解决方法是用 StartsWith Contains EndsWith

    例如:

    LIKE 'a%' => StartsWith("a")
    LIKE '%a' => EndsWith("a")
    LIKE '%a%' => Contains("a")
    LIKE 'a%b' => StartsWith("a") && EndsWith("b")
    LIKE 'a%b%' => StartsWith("a") && Contains("b")
    

    等等。。。

    注意,它并不完全等同于在SQL中使用LIKE:例如 LIKE '%abc%bcd%' Contains("abc") && Contains("bcd") . 这将匹配“abcd”,即使原始的LIKE条件不匹配,但对于大多数情况,它应该足够好。

    下面是一个示例实现,使用 PredicateBuilder LinqKit

    public static class ExpressionHelper
    {
        public static Expression<Func<T, bool>> StringLike<T>(Expression<Func<T, string>> selector, string pattern)
        {
            var predicate = PredicateBuilder.True<T>();
            var parts = pattern.Split('%');
            if (parts.Length == 1) // not '%' sign
            {
                predicate = predicate.And(s => selector.Compile()(s) == pattern);
            }
            else
            {
                for (int i = 0; i < parts.Length; i++)
                {
                    string p = parts[i];
                    if (p.Length > 0)
                    {
                        if (i == 0)
                        {
                            predicate = predicate.And(s => selector.Compile()(s).StartsWith(p));
                        }
                        else if (i == parts.Length - 1)
                        {
                            predicate = predicate.And(s => selector.Compile()(s).EndsWith(p));
                        }
                        else
                        {
                            predicate = predicate.And(s => selector.Compile()(s).Contains(p));
                        }
                    }
                }
            }
            return predicate;
        }
    }
    

    下面是如何使用它:

    var expr = ExpressionHelper.StringLike<YourClass>(x => x.Type, typeFilter);
    query = query.AsExpandable().Where(expr.Compile());
    

        2
  •  4
  •   Russell Steen    14 年前

    你可以做ESQL和下面这样的事情。。

         db.MyTables.Where("it.Type like '" + typeFilter + "'").ToList();
    
        3
  •  4
  •   Community Egal    7 年前

    这个 SqlMethods class 用于LINQ to SQL。当您使用它的方法时(公共文档告诉您不要这样做,它不是供公众使用的) IQueryable linqto Entities的提供程序不知道如何处理它或如何翻译它。

    StartsWith EndsWith 方法 String 类,linqto实体将支持它。

    但是,在本例中,通配符的数量是可变的,因此您必须下拉到ESQL级别并从中构建查询,如中所示 Nix's answer

        4
  •  0
  •   brechtvhb    9 年前

    你可以使用一个真正的like链接到实体

        <Function Name="String_Like" ReturnType="Edm.Boolean">
          <Parameter Name="searchingIn" Type="Edm.String" />
          <Parameter Name="lookingFor" Type="Edm.String" />
          <DefiningExpression>
            searchingIn LIKE lookingFor
          </DefiningExpression>
        </Function>
    

    发送给您的EDMX:

    edmx:edmx/edmx:运行时/edmx:概念模型/模式

    <schema namespace="" /> 属性

    然后在上面的命名空间中添加一个扩展类:

    public static class Extensions
    {
        [EdmFunction("DocTrails3.Net.Database.Models", "String_Like")]
        public static Boolean Like(this String searchingIn, String lookingFor)
        {
            throw new Exception("Not implemented");
        }
    }
    

    http://jendaperl.blogspot.be/2011/02/like-in-linq-to-entities.html

        5
  •  0
  •   Community Egal    4 年前

    我发帖了 my solution here

    对于实体框架6.2,可以使用 DBFunctions

    例如:

    try
    {
        using (var db = new YOUREntities())
        {
            var data = db.LenderProgram.Where(i => DbFunctions.Like(i.LenderProgramCode, "OTO%"))
                .ToList();
            return data;
        }
    }
    catch (Exception e)
    {
        e.HandleException();
    }