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).
