重构使用LINQ过滤列表

时间:2011-04-05 13:58:03

标签: linq list find

我使用了几个类似对象的列表。任何对象都有一个List属性。基本上,我需要比较几个列表。

我原本以为LINQ会是一个理想的做法,但在尝试连接,扩展方法,使用收益等之后我仍然遇到麻烦。

有关使用LINQ重构我的代码的任何建议吗?

更新:我是重构ContieneServidor(ContainsServer翻译)方法

 private static bool ContieneServidorRefactoring(List<GrupoServidorDto> datosGruposServidores, string nombreMaquina)
    {
            var total = datosGruposServidores
                 .SelectMany(g => g.Servidores)
                 .Where(x => x.Nombre.Equals(nombreMaquina)).Count();
            if (total > 0) return true;
            return false;
    }

我的代码:

var datosGruposServidores = new List<GrupoServidorDto>();    
var gruposCompletos = new List<GrupoServidorSeleccionado>();
var maquinasSeleccionadas = new List<string>();
...

// Comprobación de Máquinas
var maquinasNoEncontradas = new List<string>();
foreach (var g in gruposCompletos)
{
    foreach (var server in g.Servidores)
    {
        var encontrado = 
            ContieneServidor(datosGruposServidores, server.Nombre);
        if (!encontrado) maquinasNoEncontradas.Add(server.Nombre);
    }
}

foreach (var m in maquinasSeleccionadas)
{
    var encontrado = ContieneServidor(datosGruposServidores, m);
    if (!encontrado) maquinasNoEncontradas.Add(m);
}

if (maquinasNoEncontradas.Count > 0)
{
    var sb = new StringBuilder();
    var sep = "";
    foreach (var maq in maquinasNoEncontradas)
    {
        sb.Append(sep + maq);
        sep = ", ";
    }

    System.Diagnostics.Trace.WriteLine("Máquinas no encontradas: " + sb.ToString());
    throw new InvalidOperationException("Máquinas no encontradas: " + sb.ToString());
}

}

private static bool ContieneServidor(
    List<GrupoServidorDto> datosGruposServidores, string nombreMaquina)
{
    foreach (var g in datosGruposServidores)
    {
        var servidor = g.Servidores.Where(s => s.Nombre.Equals(nombreMaquina));
        if (servidor != null && servidor.Count() > 0) return true;
    }
    return false;
}

private static bool ContieneServidorRefactoring(List<GrupoServidorDto> datosGruposServidores, string nombreMaquina)
{
        var total = datosGruposServidores
             .SelectMany(g => g.Servidores)
             .Where(x => x.Nombre.Equals(nombreMaquina)).Count();
        if (total > 0) return true;
        return false;
}

类型:

public class GrupoServidorDto
{
    public int IdGrupo { get; set; }

    public string Nombre { get; set; }

    private List<ServidorDto> servidores = new List<ServidorDto>();

    public List<ServidorDto> Servidores
    {
        get { return servidores; }
        set { servidores = value; }
    }
}


public class ServidorDto
{
    public int Id { get; set; }

    public string Nombre { get; set; }

    public string IP { get; set; }

    public string Entorno { get; set; }

    public string Habilitado { get; set; }

    public string Tipo { get; set; }

    public int IdGrupo { get; set; }
}


[Serializable()]
public class GrupoServidorSeleccionado
{
    [XmlAttribute()]
    public int IdGrupo { get; set; }

    [XmlAttribute()]
    public string Nombre { get; set; }

    private List<ServidorSeleccionado> servidores = 
        new List<ServidorSeleccionado>();

    [XmlElement()]
    public List<ServidorSeleccionado> Servidores
    {
        get { return servidores; }
        set { servidores = value; }
    }

    [XmlAttribute()]
    public bool EstanTodasLasMaquinasSeleccionadas { get; set; }

    public GrupoServidorSeleccionado() { }
}


[Serializable()]
public class ServidorSeleccionado
{
    [XmlAttribute()]
    public int Id { get; set; }

    [XmlAttribute()]
    public string Nombre { get; set; }

    [XmlAttribute()]
    public string IP { get; set; }

    [XmlAttribute()]
    public string Entorno { get; set; }

    [XmlAttribute()] // [XmlIgnore()]
    public string Habilitado { get; set; }

    [XmlAttribute()]
    public string Tipo { get; set; }

    [XmlAttribute()]
    public int IdGrupo { get; set; }
}

2 个答案:

答案 0 :(得分:2)

我想你想要:

var maquinasNoEncontradas = gruposCompletos
                   .SelectMany(g => g.Servidores)
                   .Select(x => x.Nombre)
                   .Concat(maquinasSeleccionadas)
                   .Where(x => !ContieneServidor(datosGruposServidores, x))
                   .ToList();

然后:

if (maquinasNoEncontradas.Count > 0)
{
    // This assumes .NET 4; it's *slightly* more awkward in .NET 3.5, but
    // still simpler than doing it by hand.
    string text = string.Join(", ", maquinasNoEncontradas);

    System.Diagnostics.Trace.WriteLine("Máquinas no encontradas: " + text);
    throw new InvalidOperationException("Máquinas no encontradas: " + text);
}

可以潜在地构建以逗号分隔的版本,然后测试是否是一个空字符串......但是我不确定我会这么说。

答案 1 :(得分:1)

        string.Join(", ", gruposCompletos
                              .SelectMany(x => x.Servidores)
                              .Select(x => x.Nombre)
                              .Concat(maquinasSeleccionadas)
                              .Where(x => !ContieneServidor(datosGruposServidores, x))
                              .ToArray());