Linq IQueryable 短路空搜索参数

发布于 2024-10-04 13:53:57 字数 1477 浏览 7 评论 0原文

我有一个通用存储库,采用以下方法,

IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression);

我现在尝试通过前端提供搜索功能,其中可能已输入一个或多个参数或留空。我在短路空参数的表达式时遇到问题。

可以通过在存储库上调用以下示例来演示该问题:

public IEnumerable<Foo> Search(string param)
{
    var filteredFoos = _fooRepository.GetAllByFilter(
          f => string.IsNullOrEmpty(param) || f.Something == param );

    return filteredFoos.ToList(); // throws exception
}

如果 param 为,则使用 ToList() 枚举查询会抛出 System.NullReferenceException

我既不明白这一点也不知道如何解决它,所以任何指示表示赞赏。谢谢。

更新:为了回应下面的评论,我添加了一个空检查。我的实际代码现在看起来像这样,

var test1 = _repository.GetAllByFilter(
     r => r != null && 
         (string.IsNullOrEmpty(param) 
              || (r.Field != null && r.Field.IndexOf(param.Trim()) != -1)));

var test2 = test1.ToList(); // exception here

我仍然没有看到问题可能出在哪里。

编辑:响应评论,通用存储库GetAllByFilter代码:

public IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression)
{
    return _dataContext.GetTable<T>().Where(expression);
}

运行简单的GetAll查询

public IQueryable<T> GetAll()
 {
     return _dataContext.GetTable<T>();
 }

请注意,如果我在同一个表上 ,则不会<返回 code>null 记录(如预期)。

I have a generic repository with the following method

IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression);

I'm now trying to provide a search feature through the front end, where one or more parameters might have been entered or left blank. I'm having problems short-circuiting the expression for empty parameters.

The problem can be demonstrated by calling the following example on the repository:

public IEnumerable<Foo> Search(string param)
{
    var filteredFoos = _fooRepository.GetAllByFilter(
          f => string.IsNullOrEmpty(param) || f.Something == param );

    return filteredFoos.ToList(); // throws exception
}

Enumerating the query with ToList() throws a System.NullReferenceException if param is null.

I neither understand this nor know how to fix it, so any pointers appreciated. Thanks.

UPDATE: in response to the comments below, I added a null check. My actual code looks like this now

var test1 = _repository.GetAllByFilter(
     r => r != null && 
         (string.IsNullOrEmpty(param) 
              || (r.Field != null && r.Field.IndexOf(param.Trim()) != -1)));

var test2 = test1.ToList(); // exception here

I'm still not seeing where the problem could be.

EDIT: in response to comment, the generic repository GetAllByFilter code:

public IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression)
{
    return _dataContext.GetTable<T>().Where(expression);
}

note that if I run a simple GetAll query

public IQueryable<T> GetAll()
 {
     return _dataContext.GetTable<T>();
 }

on the same table, no null records are returned (as expected).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不乱于心 2024-10-11 13:53:57

保持简单:

public IEnumerable<Foo> Search(string param)
{
    if (string.IsNullOrEmpty(param))
    {
        return this.fooRepository.GetAll().ToArray();
    }

    return this.fooRepository.GetAllByFilter(o => o.Field.Contains(param.Trim())).ToArray();
}

keep it simple:

public IEnumerable<Foo> Search(string param)
{
    if (string.IsNullOrEmpty(param))
    {
        return this.fooRepository.GetAll().ToArray();
    }

    return this.fooRepository.GetAllByFilter(o => o.Field.Contains(param.Trim())).ToArray();
}
酷到爆炸 2024-10-11 13:53:57

蛋糕。

    public IEnumerable<Foo> Search(string param)
    {
        Expression<Func<Foo, bool>> shortCircuit = a => true;
        Expression<Func<Foo, bool>> normal = a => a.Something == param;

        var filteredFoos = _fooRepository.GetAllByFilter(
            string.IsNullOrEmpty(param) ? shortCircuit : normal);

        return filteredFoos.ToList(); // no more exception.
    }

您只需记住,您不能将任何内容放入这些 IQueryable 方法中并期望它们能够理解。您也许可以将 ShortCircuit 表达式设置为静态。

cake.

    public IEnumerable<Foo> Search(string param)
    {
        Expression<Func<Foo, bool>> shortCircuit = a => true;
        Expression<Func<Foo, bool>> normal = a => a.Something == param;

        var filteredFoos = _fooRepository.GetAllByFilter(
            string.IsNullOrEmpty(param) ? shortCircuit : normal);

        return filteredFoos.ToList(); // no more exception.
    }

You just gotta remember, you can't throw anything into those IQueryable methods and expect them to understand. You can probably make shortCircuit expression to static.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文