Problem
I have an IQueryable, and I want to search it based on roles. An user can have multiple roles so I want to be able to add multiple search conditions (one on top of another).
public void OnGet()
{
var productionUnits = _context.ProductionUnits;
IQueryable query = productionUnits;
if (User.IsInRole(CustomRole.AdministratorUAP1))
{
query = productionUnits.Where(c => c.Id == (int)ProductionUnitEnum.UAP1);
}
if (User.IsInRole(CustomRole.AdministratorUAP2))
{
query = productionUnits.Where(c => c.Id == (int)ProductionUnitEnum.UAP2);
}
...
}
Expected Output
If the user is in multiple roles, for example UAP1 and UAP2, I want the query to get both of them in the Where clause. Is there any way to achieve this (I know I could do List.AddRange()
, but I really want to update the query instead). Is there any way to achieve this?
CodePudding user response:
I would creeate a list of roles for the user and use Contains
in the query:
var roleIds = new List<int>();
if (User.IsInRole(CustomRole.AdministratorUAP1))
{
roleIds.Add(ProductionUnitEnum.UAP1);
}
if (User.IsInRole(CustomRole.AdministratorUAP2))
{
roleIds.Add(ProductionUnitEnum.UAP2)
}
var query = productionUnits.Where(c => roleIds.Contains(c.Id));
That will add an IN
clause to your query for those two roles. If you have more than two roles just add them to the list as appropriate.
CodePudding user response:
Each Linq function returns an IQueryable<>
, so just keep reusing that:
IQueryable<T> query = productionUnits; // note the <T>
if (User.IsInRole(CustomRole.AdministratorUAP1))
query = query.Where(c => c.Id == (int)ProductionUnitEnum.UAP1);
if (User.IsInRole(CustomRole.AdministratorUAP2))
query = query.Where(c => c.Id == (int)ProductionUnitEnum.UAP2);
If the user is in multiple roles, for example UAP1 and UAP2
Then your database is fundamentally broken, you're checking those values against a single field: c.Id
. One number can't be both values at the same time.