C# 使用两个参数之一的LINQ语句

C# 使用两个参数之一的LINQ语句,c#,linq,C#,Linq,我正在写一份LINQ声明。我有一个城市表,其中记录有countryId或stateId。我只想写一条语句,让where子句检查两个参数中哪一个是null,然后选择一个不是null的 以下是我的工作内容: public List<City> Cities(int? countryTypeId, int? stateTypeId) { if (countryTypeId == null && stateTypeId == null) return

我正在写一份LINQ声明。我有一个城市表,其中记录有
countryId
stateId
。我只想写一条语句,让where子句检查两个参数中哪一个是null,然后选择一个不是null的

以下是我的工作内容:

public List<City> Cities(int? countryTypeId, int? stateTypeId)
{
    if (countryTypeId == null && stateTypeId == null) 
        return null;

    return _db.City
        .Where(x => x.StateTypeId == stateTypeId
                    && x.CountryTypeId == countryTypeId)
        .OrderBy(x => x.Description)
        .ToDTOs();
}
公共列表城市(int?countryTypeId,int?stateTypeId)
{
如果(countryTypeId==null&&stateTypeId==null)
返回null;
返回_db.City
.其中(x=>x.StateTypeId==StateTypeId
&&x.CountryTypeId==CountryTypeId)
.OrderBy(x=>x.Description)
.ToDTOs();
}

我是LINQ的新手,我知道这段代码不正确,只是添加它作为上下文。

如果
国家
ID都是
>0
您只需执行此操作,无需检查空值

 .Where(x => x.StateTypeId == stateTypeId.GetValueOrDefault()
                    && x.CountryTypeId == countryTypeId.GetValueOrDefault())
否则,如注释中所述,如果这些可为null的输入有值或无值,则需要添加条件

编辑:在看到一些注释后,如果您正在根据任一参数查找
城市列表
,那么您应该在where条件下使用
|
而不是
&

Where(x => (stateTypeId.HasValue && stateTypeId.Value == x.StateTypeId) 
     || (countryTypeId.HasValue && countryTypeId.Value == x.CountryTypeId))
注意顺序问题,此代码将首先检查
stateTypeId
是否有值,如果有值,则只将
城市
与该
stateTypeId

_db.City.Where(c => c.CountryTypeId?.Equals(countryTypeId) ?? false 
    | c.StateTypeId?.Equals(stateTypeId) ?? false);
Using-当类型Id为null时,使用返回false并使匹配失败-否则检查是否相等并返回匹配

请注意此处的OR运算符

我不确定是否是这种情况,但如果其中一个输入参数始终为null,并且保证条目始终有一个属性为null,那么以下将是一个很酷的解决方案:

_db.City.Where(c => (c.CountryTypeId ?? c.StateTypeId) == (countryTypeId ?? stateTypeId))

我的DBA已经充分打动了我的头脑,忽略查询中的参数(例如:WHERE Field=@PARAM或@PARAM为NULL)可能会导致非常糟糕的结果。因此,我鼓励您有条件地只添加您绝对需要的参数。幸运的是,考虑到您只使用两个可能的参数,这是微不足道的

从查询的基础开始,然后添加到其中

var queryBase = _db.City.OrderBy(x => x.Description);

if (countryTypeId.HasValue)
{
    queryBase = queryBase.Where(x => x.CountryTypeId == countryTypeId);
}

if (stateTypeId.HasValue)
{
    queryBase = queryBase.Where(x => x.StateTypeId == stateTypeId);
}

return queryBase.ToDTOs(); // or .ToList() for a more universal outcome

如果参数是互斥的,一个参数取代另一个参数,那么添加您可能需要的任何逻辑。

这不是linq问题,真的;这是一个布尔逻辑问题:
其中(x=>(!stateTypeId.HasValue | | stateTypeId.Value==x.stateTypeId)和(!countryTypeId.HasValue | countryTypeId.Value==x.countryTypeId))
。对于短路计算,当
stateTypeId
没有值时,该子表达式始终为
true
。如果两个参数都为null,则两个子表达式都为true,查询将返回所有内容。@EdPlunkett在处理LINQ to SQL/EF时,我认为可以公平地说这是一个LINQ问题-任何建议的解决方案都必须有SQL翻译。(
HasValue
由LINQ翻译成SQL。)您的意思是检查参数是否为
null
还是数据库字段是否为
null
或两者兼而有之?它是
x.StateTypeId
部分,因为它是一个数据库字段。@NetMage,它在db上是否为null并不重要,这是他正在检查的参数。在给出否定答案之前,先看问题。如果它在db中可以为null,linq可以轻松地处理它,而不需要任何validation@EdPlunkett不是我的问题。@NetMage问题不是你写的。不过,您可能猜对了。@NetMage,如果列在db中可以为null,
linq
可以在没有任何null检查验证的情况下处理它,而这不是他所要求的。谢谢