首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在实体框架中为客户使用谓词LINQ查询,扩展方法“按单词搜索”

如何在实体框架中为客户使用谓词LINQ查询,扩展方法“按单词搜索”
EN

Stack Overflow用户
提问于 2016-07-05 14:07:54
回答 1查看 4.1K关注 0票数 2

我希望使用谓词构建自定义linq查询。

而不是使用静态Where子句,即.

代码语言:javascript
运行
复制
public IEnumerable<Entities.BusinessDirectory.BDEntity> Search(string searchExpression)
{
    var db = new ApplicationDbContext();
    return db.BDEntities
             .Where(x => searchExpression.Split(' ').Any(y => x.Value.Contains(y)));
}

..。我正在用泛型方法DbContext扩展Search(predicate, searchExpression),它将具有与静态方法相同的效果(见上文)

代码语言:javascript
运行
复制
public static class DbContextExtensions
{
    public static IEnumerable<T> Search<T>(
        this DbSet<T> dbSet, 
        Expression<Func<T, object>> predicate, 
        string searchExpression)
      where T : class, new()
    {
        //Experimental
        return dbSet
            .Where(x => searchExpression.Split(' ').Any(y => predicate.Contains(x)));
    }
}

但是,我收到以下错误:

错误6实例参数:无法从“System.Linq.Expressions.Expression>”转换为“System.Linq.ParallelQuery”Extensions.cs

EN

回答 1

Stack Overflow用户

发布于 2016-07-05 14:13:54

简单的答案是,您可以只向查询Where子句添加一个谓词,请记住,Where谓词的定义是它返回bool。最后,表达式必须是boolean表达式,才能添加到Where子句中。

代码语言:javascript
运行
复制
Expression<Func<BDEntity, bool>> predicate = (BDEntity entity) => entity.Field == "TEST";
var query = context.BDEntities;

if (predicate != null)
    query = query.Where(predicate);

// expand to get the results.
var results = query.ToList();

动态表达式

如果您需要在运行时构建一个像_ => _.MyFieldValue == "TEST"这样的表达式,那就更棘手了。

给定谓词_ => _.DatabaseField和字符串值"TEST",创建一个适合实体框架的表达式来创建测试谓词的where子句。

此方法将生成一个适当的Equal表达式。

代码语言:javascript
运行
复制
public static Expression<Func<T, bool>> BuildEqualPredicate<T>(
    Expression<Func<T, string>> memberAccessor,
    string term)
{
    var toString = Expression.Convert(Expression.Constant(term), typeof(string));
    Expression expression = Expression.Equal(memberAccessor.Body, toString);
    var predicate = Expression.Lambda<Func<T, bool>>(
        expression,
        memberAccessor.Parameters);
    return predicate;
}

将通过以下断言:

代码语言:javascript
运行
复制
var expression = Predicate.BuildEqualPredicate<MyDbEntity>(_ => _.DatabaseField, "TEST");
expression.Compile()
    .Invoke(new MyDbEntity { DatabaseField = "TEST" })
    .Should().BeTrue();
expression.Compile()
    .Invoke(new MyDbEntity { DatabaseField = "ANOTHERVALUE"})
    .Should().BeFalse();

通过在where子句中包含谓词,实体框架可以使用谓词。

代码语言:javascript
运行
复制
var predicate = PredicateExtensions.BuildEqualPredicate<MyDbEntity>(
    _ => _.DatabaseField,
    "TEST");
var results = context.DbEntity.Where(predicate).ToList();

另外

您可以对成员表达式做更多的工作,比如使用StartsWithContains来创建更复杂的谓词。

代码语言:javascript
运行
复制
Expression<Func<T, string>> memberAccessor = _ => _.DBEntityField;

您可以动态地创建这样的谓词,在这个示例中,它创建一个谓词来检查字符串StartsWith是否是一个特定的值,or is null

代码语言:javascript
运行
复制
private Expression<Func<T, bool>> BuildPredicate(
    string term,
    Expression<Func<T, string>> memberAccessor)
{
    var startsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
    var isNull = typeof(string).GetMethod("IsNullOrEmpty", new[] { typeof(string) });
    var toString = Expression.Convert(Expression.Constant(term), typeof(string));
    Expression expression = Expression.Call(
        memberAccessor.Body,
        startsWith,
        new Expression[] { toString });
    expression = Expression.Or(expression, Expression.Call(
        isNull,
        toString));
    var predicate = Expression.Lambda<Func<T, bool>>(
        expression,
        memberAccessor.Parameters);
    return predicate;
}

这将给出一个计算结果如下的表达式:

代码语言:javascript
运行
复制
Expression<Func<BDEntity, bool>> expression = _ => 
   string.IsNullOrEmpty(term)
   || _.DBEntityField.StartsWith(term)

这个表达式有几个优点:

  • 它可以转换成合适的SQL
  • termnullempty时,返回所有记录。
  • StartsWith确保可以使用适当的索引。

expression可以类似地添加到使用query = query.Where(expression)的查询中,用Contains代替StartsWith将搜索字符串中的任何出现,但是将放弃任何SQL索引优化,因此这是禁忌的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38205592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档