Тернарный оператор в LINQ where для обнуляемого типа bool столбец
Может ли кто-нибудь увидеть что-нибудь неправильное с тернарным в where этого утверждения linq:
var organizations = Context.Set<Domain.Content.Organisation>()
.Where(x => x.ShowCompanyPage == (showCompanyPagesOnly ? true : x.ShowCompanyPage))
Если showCompanyPagesOnly имеет значение true, я получаю 4 результата, это верно только четыре компании имеют ShowCompanyPage = true.
Однако, если я установлю его в false, я ожидаю 1000 + результатов (все компании). Но я все равно получаю только 4.
Разве моя логика не такова:
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 является нулевым столбцом bool.
Полный код:
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;
}
3 ответов:
Иногда, когда логика становится слишком сложной, лучший ответ-это перевернуть вопрос с ног на голову, в настоящее время вы задаете
Если showCompanyPagesOnly является true, как я могу получить только те, с с ShowCompanyPage = true
Если вы поменяете это с get everything, если showCompanyPagesOnly не истинно, и ваша логика станет простым или утверждением
Либо showCompanyPagesOnly не является истинным, либо ShowCompanyPage является истинным который является
x => (!showCompanyPagesOnly) || x.ShowCompanyPageВозможно, вам придется сделать это
x => (!showCompanyPagesOnly) || (x.ShowCompanyPage ?? false)/*default value depends on if you want to treat null as true or false*/)Принять во внимание ничтожность
Это гораздо лучший подход, так как он будет генерировать два различных запроса LINQ, и это позволит SQL Server генерировать два различных плана запросов, которые в большинстве случаев могут значительно повлиять на производительность запросов:
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; }
Попробуйте вот что:
.Where(x => showCompanyPagesOnly ? x.ShowCompanyPage == true : true)Здесь естьскрипка .
Функция
Where()возвращает записи, удовлетворяющие условию, поэтому условие должно быть выполнено в Булевом виде (т. е. либоtrue, либоfalse). Если вы помещаете значениеtrueв условие, то вы фактически просите функциюWhere()вернуть все записи. Это похоже на:if(true){ //do something. }Как вы знаете, это всегда будет выполнять "сделать что-то".
Comments