Home > Back-end >  Add Where clause to IQueryable<T> in function?
Add Where clause to IQueryable<T> in function?

Time:12-20

Why Where clause is not applied to IQueryable in the AddWhereToQuery function ?

It should be reference type and I cannot see why this code should not work as I expect.


[Route("/testing")]
public class MyTestController : ControllerBase
{
    private readonly YieldigoDbContext _db;

    public MyTestController(YieldigoDbContext db)
    {
        _db = db;
    }


    [HttpGet]
    public IActionResult Get()
    {
        var queryable = _db.Articles.AsQueryable();
        AddWhereToQuery(queryable);

        var queryString = queryable.ToQueryString();

        return Ok(queryString);
    }

    private void AddWhereToQuery(IQueryable<Article> queryable)
    {
        queryable = queryable.Where(x => x.Status == ArticleStatus.Active);
    }
}

When I add ref keyword it works just fine, but why ref is necessary

[Route("/testing")]
public class MyTestController : ControllerBase
{
    private readonly YieldigoDbContext _db;

    public MyTestController(YieldigoDbContext db)
    {
        _db = db;
    }


    [HttpGet]
    public IActionResult Get()
    {
        var queryable = _db.Articles.AsQueryable();
        AddWhereToQuery(ref queryable);

        var queryString = queryable.ToQueryString();

        return Ok(queryString);
    }

    private void AddWhereToQuery(ref IQueryable<Article> queryable)
    {
        queryable = queryable.Where(x => x.Status == ArticleStatus.Active);
    }
}

CodePudding user response:

You should change your code in this way:

[HttpGet]
public IActionResult Get()
{
    var queryable = _db.Articles.AsQueryable();
    queryable = AddWhereToQuery(queryable);

    var queryString = queryable.ToQueryString();

    return Ok(queryString);
}

private IQueryable<Article> AddWhereToQuery(IQueryable<Article> queryable)
{
    return queryable.Where(x => x.Status == ArticleStatus.Active);
}

CodePudding user response:

In your Get() method you create a variable var queryable which we'll call 1 that contains a reference to that instance which we'll call A. So queryable holds a reference 1->A.

Now you call the function AddWhereToQuery(... queryable). The queryable is a copy of your variable which we'll call 2 that points to the same reference 2->A.

So now you create a new instance of a queryable object which we'll call B and you save that in your queryable in the scope of the function. So now 2->B.

As you see at no point have you changed what 1 points to so the instance with your Where filter is never used. If you were to use ref is won't make a copy but will pass the variable itself (whether struct or reference type).

  • Related