LINQ(.Contains())查询整个DbSet

时间:2013-07-01 15:57:25

标签: c# sql entity-framework

public List<DbSet> Get(String q = null)
{
    List<DbSet> objs = new List<DbSet>();

    if (!string.IsNullOrEmpty(q) && q != "undefined")
    {
        objs = from dealer in db.Dealers
               where dealer.Contains
               ......(?????)
    }
}

我的dbcontext类中有4个DbSet。我能够像这样进行搜索

objs = from dealer in db.Dealers
       where dealer.Name.Contains(q)

但是我希望能够做类似的事情,除了搜索经销商的所有字段,而不仅仅是名字。所有字段都是字符串

修改

好的,所以我开始认为这不是我想要实现的最佳方式。我正在研究一种叫做“em>”全文搜索“的东西。有人可以向我解释这是如何在实体中工作或给我一个良好的资源链接

3 个答案:

答案 0 :(得分:2)

您可以编写一个linq扩展方法:

查看我的博文。
http://jnye.co/Posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees

(类也在github中:https://github.com/ninjanye/SearchExtensions

public static IQueryable<T> Search<T>(this IQueryable<T> source, string searchTerm, params Expression<Func<T, string>>[] stringProperties)  
{  
    if (String.IsNullOrEmpty(searchTerm))  
    {  
        return source;  
    }  

    var searchTermExpression = Expression.Constant(searchTerm);  

    //Variable to hold merged 'OR' expression  
    Expression orExpression = null;  
    //Retrieve first parameter to use accross all expressions  
    var singleParameter = stringProperties[0].Parameters.Single();  

    //Build a contains expression for each property  
    foreach (var stringProperty in stringProperties)  
    {  
        //Syncronise single parameter accross each property  
        var swappedParamExpression = SwapExpressionVisitor.Swap(stringProperty, stringProperty.Parameters.Single(), singleParameter);  

        //Build expression to represent x.[propertyX].Contains(searchTerm)  
        var containsExpression = BuildContainsExpression(swappedParamExpression, searchTermExpression);  

        orExpression = BuildOrExpression(orExpression, containsExpression);  
    }  

    var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, singleParameter);  
    return source.Where(completeExpression);  
}  

private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)  
{  
    if (existingExpression == null)  
    {  
        return expressionToAdd;  
    }  

    //Build 'OR' expression for each property  
    return Expression.OrElse(existingExpression, expressionToAdd);  
}  

private static MethodCallExpression BuildContainsExpression<T>(Expression<Func<T, string>> stringProperty, ConstantExpression searchTermExpression)  
{  
    return Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);  
}  

您还需要这个课程:

//Create SwapVisitor to merge the parameters from each property expression into one  
public class SwapVisitor : ExpressionVisitor  
{  
    private readonly Expression from, to;  
    public SwapVisitor(Expression from, Expression to)  
    {  
        this.from = from;  
        this.to = to;  
    }  
    public override Expression Visit(Expression node)  
    {  
        return node == from ? to : base.Visit(node);  
    }  
    public static Expression Swap(Expression body, Expression from, Expression to)  
    {  
        return new SwapVisitor(from, to).Visit(body);  
    }  
}  

然后您可以编写如下内容:

db.Dealers.Search(q, x => x.Field1,    
                     x => x.Field2, 
                     ...  
                     x => x.Field20)

答案 1 :(得分:1)

对不起,这里没有捷径:

objs = from dealer in db.Dealers
       where dealer.Name.Contains(q) || 
             dealer.Field2.Contains(q) ||
             ...
             dealer.Field20.Contains(q)
       select dealer;

您必须指定要搜索值的字段。

答案 2 :(得分:0)

您可以手动为所有字段写入条件:

objs = from dealer in db.Dealers
       where dealer.Name.Contains(q) ||
             dealer.Foo.Contains(q) ||  
             // etc
             dealer.Bar.Contains(q)
       select dealer;

没有简单的方法可以告诉实体框架在某些条件下检查实体的所有属性。