LINQ中的三元运算符可空的bool列的Where子句

时间:2015-10-13 14:03:35

标签: c# linq where-clause ternary-operator

任何人都可以在这个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 个答案:

答案 0 :(得分:4)

有时,当逻辑变得过于复杂时,最好的答案是将问题颠倒过来,目前你在问

如果showCompanyPagesOnly为true,我如何只获得带有ShowCompanyPage = true的那些

如果你把它与get一起交换,除非showCompanyPagesOnly为true并且你的逻辑变成一个简单的OR语句

showCompanyPagesOnly不为true或ShowCompanyPage为true

   x => (!showCompanyPagesOnly) || (x.ShowCompanyPage ?? false)/*default value depends on if you want to treat null as true or false*/)

你可能需要这样做

[1 2 -1 -2]

考虑到可空性

答案 1 :(得分:3)

这是一种更好的方法,因为它会生成两个不同的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;

}

答案 2 :(得分:1)

试试这个:

.Where(x => showCompanyPagesOnly ? x.ShowCompanyPage == true : true)

这是fiddle

Where()函数返回满足条件的记录,因此条件必须求值为布尔值(即truefalse)。如果您将值true置于条件中,那么您有效地要求Where()函数返回所有记录。它类似于:

if(true){
    //do something.
}

如你所知,这将始终执行&#34;做某事&#34;。