【问题标题】:Filter with several nullable conditions an IEnumerable - List using lambda expressions [closed]使用多个可空条件过滤 IEnumerable - 使用 lambda 表达式列出 [关闭]
【发布时间】:2014-05-15 00:33:08
【问题描述】:

我使用 .NET 4.5 和 VS 2012。

我有一个类模型(来自 Xml Deserialize),现在我已经“过滤”了它。

我有几个条件的可空值。

使用 lambda 表达式的最佳做法是什么?

我有这个代码:

    public static List<MyDto> ListarEntornosYContenidoEntorno(int? id, string name, int? id2, string name2, string entorno, bool? shouldBe, string mode)
    {
        IEnumerable<MyDto> list = Model.Environments;

        if (id.HasValue)
            list = list.Where(item => item.IdCiaDespliegue.Equals(id.Value));

        if (!name.IsNullOrWhiteSpace())
            list = list.Where(item => item.NombreCiaDespliegue.Equals(name));

        if (id2.HasValue)
            list = list.Where(item => item.IdContenidoEntorno.Equals(id2.Value));

        if (!name2.IsNullOrWhiteSpace())
            list = list.Where(item => item.ContenidoEntorno.Equals(name2));

        if (!entorno.IsNullOrWhiteSpace())
            list = list.Where(item => item.Entorno.Equals(entorno));

        if (shouldBe.HasValue)
            list = list.Where(item => item.DebeEtiquetar.Equals(shouldBe));

        if (!mode.IsNullOrWhiteSpace())
            list = list.Where(item => item.Modo.Equals(mode));

        return list.ToList();

    }

【问题讨论】:

  • 看起来不错,有问题吗?
  • 我会找到好的做法,更易读、更清晰。
  • 如果您想对所有过滤器使用一种方法,您的方法似乎很明确,不是吗?
  • 这类问题属于codereview.stackexchange.com。

标签: c# linq lambda where-clause conditional-statements


【解决方案1】:

您可以执行以下操作(不确定是否更具可读性):

IEnumerable<MyDto> list = Model.Environments;

return list.Where(item => !id.HasValue                       || item.IdCiaDespliegue == id.Value)
           .Where(item => string.IsNullOrWhiteSpace(name)    || item.NombreCiaDespliegue == name)
           .Where(item => !id2.HasValue                      || item.IdContenidoEntorno == id2.Value)
           .Where(item => string.IsNullOrWhiteSpace(name2)   || item.ContenidoEntorno == name2)
           .Where(item => string.IsNullOrWhiteSpace(entorno) || item.Entorno == entorno)
           .Where(item => !shouldBe.HasValue                 || item.DebeEtiquetar == shouldBe)
           .Where(item => string.IsNullOrWhiteSpace(mode)    || item.Modo == mode)
           .ToList();

诀窍是当您的选择器为空或为空时返回true,这样就不会过滤掉任何项目。

请注意,我将您所有的.Equals 替换为==,因为在这种情况下它们是等价的,而== 在我看来更具可读性。

【讨论】:

  • 这不是比 OP 的代码更多而是更少的可读性,甚至更容易出错。也更难调试。
  • 为什么是x ? true : y 而不是x || y
【解决方案2】:

我已经为您提供了一种方法来概括下面的可空整数;我相信你可以对字符串做类似的事情。此外,您应该考虑更改您的 API,以便此方法接受“过滤条件”列表或类似的列表。

var intMap = new Dictionary<int?, Func<Environment, int>> 
{
    { id, item => item.IdCiaDespliegue },
    { id2, item => item.IdContenidoEntorno },
    { entorno, item => item.DebeEtiquetar }
}

var list = Model.Environments;

foreach(var pair in intMap)
{
    if(pair.Key != null)
        list = list.Where(item => pair.Value(item).Equals(pair.Key.Value));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多