Reputation: 1419
Can anyone see anything wrong with the ternary in the where of this linq statement:
var organizations = Context.Set<Domain.Content.Organisation>()
.Where(x => x.ShowCompanyPage == (showCompanyPagesOnly ? true : x.ShowCompanyPage))
if showCompanyPagesOnly is set to true, I get 4 results, this is correct only four companies have ShowCompanyPage = true.
However if I set it to false, I expect 1000+ results (all companies). But I STILL only get 4.
Is my logic not:
if showCompanyPagesOnly is true, then give me results where x.ShowCompanyPage == true
else give me results where x.ShowCompanyPage = whatever is in the column (ie ALL Organisations)
?
x.ShowCompanyPage is a nullable bool column.
Full code:
public Result<IList<Organisation>> GetAllOrganisations(bool showCompanyPagesOnly = false)
{
var result = new Result<IList<Organisation>>();
try
{
var organizations = Context.Set<Domain.Content.Organisation>()
.Where(x => x.ShowCompanyPage == (showCompanyPagesOnly == true ? true : x.ShowCompanyPage)) // show only company pages or show all
.AsNoTracking()
.Select(x => new DataContracts.Content.Organisation
{
Id = x.Id,
Name = x.Name,
OrganisationTypeId = x.OrganisationTypeId,
IsCustomer = x.IsCustomer,
SeoName = x.SeoName,
Description = x.Description,
Website = x.Website
}).OrderBy(x => x.Name).ToList();
result.Data = organizations;
}
catch (Exception ex)
{
result.SetException(ex);
HandleError(ex);
}
return result;
}
Upvotes: 3
Views: 12508
Reputation: 21477
This is a much better approach, as it will generate two distinct LINQ queries, and this will allow SQL Server to generate two distinct query plans, which can in most cases greatly affect the performance of the queries:
public Result<IList<Organisation>> GetAllOrganisations(bool showCompanyPagesOnly = false)
{
var result = new Result<IList<Organisation>>();
try
{
var organizations = Context.Set<Domain.Content.Organisation>()
.AsNoTracking();
if (showCompanyPagesOnly)
organizations=organization
.Where(x => x.ShowCompanyPage == true);
result.Data = organizations
.Select(x => new DataContracts.Content.Organisation
{
Id = x.Id,
Name = x.Name,
OrganisationTypeId = x.OrganisationTypeId,
IsCustomer = x.IsCustomer,
SeoName = x.SeoName,
Description = x.Description,
Website = x.Website
}).OrderBy(x => x.Name).ToList();
}
catch (Exception ex)
{
result.SetException(ex);
HandleError(ex);
}
return result;
}
Upvotes: 3
Reputation: 25351
Try this:
.Where(x => showCompanyPagesOnly ? x.ShowCompanyPage == true : true)
Here is a fiddle.
The Where()
function returns records that satisfy the condition, so the condition must evaluate to a Boolean (i.e. either true
or false
). If you put the value true
in the condition, then you're effectively asking the Where()
function to return all records. It is similar to:
if(true){
//do something.
}
As you know this will always execute the "do something".
Upvotes: 1
Reputation: 5500
Sometimes when logic is getting too complex the best answer is the turn the question upside down, currently you are asking
if showCompanyPagesOnly is true how do i get only the ones with with ShowCompanyPage = true
if you swap that with get everything unless showCompanyPagesOnly is true and your logic becomes a simple OR statement
either showCompanyPagesOnly is not true or ShowCompanyPage is true which is
x => (!showCompanyPagesOnly) || x.ShowCompanyPage
you may need to make that
x => (!showCompanyPagesOnly) || (x.ShowCompanyPage ?? false)/*default value depends on if you want to treat null as true or false*/)
to take into account the nullability
Upvotes: 4