可空 bool 列的 LINQ Where 子句中的三元运算符
Ternary Operator in LINQ Where clause for nullable bool column
任何人都可以看到这个 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;
}
试试这个:
.Where(x => showCompanyPagesOnly ? x.ShowCompanyPage == true : true)
这里是fiddle.
Where()
函数 returns 记录满足条件,因此条件必须计算为布尔值(即 true
或 false
)。如果您将值 true
放入条件中,那么您实际上是在请求 Where()
函数 return 所有记录。它类似于:
if(true){
//do something.
}
如您所知,这将始终执行 "do something"。
有时当逻辑变得太复杂时,最好的答案就是把问题颠倒过来,目前你在问
如果 showCompanyPagesOnly 为真,我如何只获得带有 ShowCompanyPage = true 的那些
如果您将其与 get everything 交换,除非 showCompanyPagesOnly 为 true 并且您的逻辑变为简单的 OR 语句
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 服务器生成两个不同的查询计划,这在大多数情况下会极大地影响查询的性能:
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;
}
任何人都可以看到这个 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;
}
试试这个:
.Where(x => showCompanyPagesOnly ? x.ShowCompanyPage == true : true)
这里是fiddle.
Where()
函数 returns 记录满足条件,因此条件必须计算为布尔值(即 true
或 false
)。如果您将值 true
放入条件中,那么您实际上是在请求 Where()
函数 return 所有记录。它类似于:
if(true){
//do something.
}
如您所知,这将始终执行 "do something"。
有时当逻辑变得太复杂时,最好的答案就是把问题颠倒过来,目前你在问
如果 showCompanyPagesOnly 为真,我如何只获得带有 ShowCompanyPage = true 的那些
如果您将其与 get everything 交换,除非 showCompanyPagesOnly 为 true 并且您的逻辑变为简单的 OR 语句
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 服务器生成两个不同的查询计划,这在大多数情况下会极大地影响查询的性能:
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;
}