2011-04-25 222 views
2

搜索我有以下SQL查询 -实施SQL“和”使用实体框架

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

如何使用EF实现它?我需要分解搜索字符串,然后对每个关键字进行“AND”搜索。我有以下的,但这不是我想要的东西 -

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我能做什么?

+0

在查询实体框架数据模型时,可以使用LINQ来完成此操作。我会尽量在短时间内汇总一个例子。 – mservidio 2011-04-25 19:59:29

+0

这将是伟大的,谢谢! – tempid 2011-04-25 20:01:30

回答

1

这里的我如何得到它的工作 -

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

Source

2

我没有对数据库进行测试,但您应该能够创建实体框架模型,然后进行查询。您可以添加更多有条件的地方,要fullfill您的所有需求:

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(); 
    } 
} 
+0

您可能必须在context.Communities调用中执行ToList()。我记不住头脑,尽管我不认为任何Entity Framework数据库提供者都支持.Contains。我认为这必须在通用列表或内存中执行,但在调用数据库时不受支持。 – mservidio 2011-04-25 20:10:31

+0

此外,我不确定你在做什么.Split方法,并循环通过多个结果。但是,如果您知道需要查询的字段数量,并且只有一个搜索字符串需要查询,那么您可以简单地将所有这些内容放在实体框架linq调用中,并使用where子句,而不需要使用contains 。 – mservidio 2011-04-25 20:15:08

+0

我测试了你的代码片段,但恐怕它不会带来任何结果。 'var allcontacts = db.LocalContacts.ToList(); var filteredLocalContacts = allcontacts.Where(c => searchTextLowerCase.Contains(c.Name))。ToList(); ucLocalContactsList.Bind(filteredLocalContacts);' – tempid 2011-04-25 20:26:17

2

这是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); 
     } 
    } 
+0

我收到以下消息 - LINQ表达式LINQ to Entities不支持节点类型“Invoke”。我的代码'var allcontacts = db.LocalContacts; var predicate = PredicateBuilder.False (); foreach(var in searchTextLowerCase) { predicate = predicate.Or(x => x.Name.ToLower()。Contains(s)); } var filteredLocalContacts = allcontacts。凡(谓语); ucLocalContactsList.Bind(filteredLocalContacts.ToList());'grr ..为什么它不能正确地格式化代码? – tempid 2011-04-25 20:34:45

+0

啊,看起来我需要安装LINQKit才能工作。 – tempid 2011-04-25 20:44:24

+0

没错!我没有回想到EF的这种限制。来自LINQKit的'AsExpandable()'会让你超越这个。 – Sorax 2011-04-25 20:49:48