Реализация поиска SQL «И» с использованием Entity Framework - PullRequest
2 голосов
/ 25 апреля 2011

У меня следующий запрос SQL -

SELECT * FROM dbo.LocalContacts WHERE name LIKE '%taiwan%' AND name LIKE '%mvp%'

Как мне реализовать его с помощью EF?Мне нужно разбить строку поиска, а затем выполнить поиск «И» для каждого из ключевых слов.У меня есть следующее, но это не то, что я хотел -

var searchTextLowerCase = Request.QueryString["q"].ToLower().Split(' ');
            foreach (var s in searchTextLowerCase)
            {
                foreach (var x in communities)
                {
                    if (
                        (!string.IsNullOrWhiteSpace(x.Name) && x.Name.ToLower().Contains(s)) ||
                        (!string.IsNullOrWhiteSpace(x.Acronym) && x.Acronym.ToLower().Contains(s)) ||
                        (!string.IsNullOrWhiteSpace(x.OwnerFirstName) && x.OwnerFirstName.ToLower().Contains(s)) ||
                        (!string.IsNullOrWhiteSpace(x.OwnerEmail) && x.OwnerEmail.ToLower().Contains(s)) ||
                        (!string.IsNullOrWhiteSpace(x.OwnerLastName) && x.OwnerLastName.ToLower().Contains(s)) ||
                        )
                    {
                        if (!filteredCommunities.Exists(y => y.Id == x.Id))
                            filteredCommunities.Add(x);
                    }
                }
            }

Я могу создать запрос SQL на лету и выполнить его к БД, но я могу сделать это с помощью EF?

Ответы [ 3 ]

2 голосов
/ 26 апреля 2011

Это один из способов сделать это с PredicateBuilder:

var predicate = PredicateBuilder.False<Community>();
foreach(var s in searchTextLowerCase)
{
    predicate = predicate.Or(x => x.Name.ToLower().Contains(s));
    predicate = predicate.Or(x => x.Acronym.ToLower().Contains(s))
    //.. etc
}
var filteredCommunities = communities.Where(predicate);

Источник для PredicateBuilder:

public static class PredicateBuilder
    {
      public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
      public static Expression<Func<T, bool>> False<T> () { return f => false; }

      public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                          Expression<Func<T, bool>> expr2)
      {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
              (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
      }

      public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                           Expression<Func<T, bool>> expr2)
      {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
              (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
      }
    }
2 голосов
/ 26 апреля 2011

Я не проверял это на БД, хотя вы должны быть в состоянии создать модель Entity Framework и затем запросить ее.Вы можете добавить больше условий, чтобы удовлетворить все ваши требования:

static void Main(string[] args)
{
    string holder = "A B C D E";
    string[] searchTextLowerCase = holder.ToLower().Split(' ');

    using (Model1Container context = new Model1Container())
    {
        var q = context.Communities;
        List<Community> communities = q.Where(c => searchTextLowerCase.Contains(c.Name)).ToList();
    }
}
1 голос
/ 28 апреля 2011

Вот как я заставил его работать -

IQueryable<Product> SearchProducts (params string[] keywords)
{
  IQueryable<Product> query = dataContext.Products;

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    query = query.Where (p => p.Description.Contains (temp));
  }
  return query;
}

Источник

...