Refactor to filtering lists using LINQ
I use several lists of similar objects. Anyone object has a List property. Basically, I need compare several lists.
I would have thought that LINQ would be an ideal way of doing this but after trying joins, extension methods, using yields, etc. I'm still having trouble.
any suggestions for refactor my code to using LINQ ?
Update: I'm refactor ContieneServidor (ContainsServer translate) method
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;
}
My code:
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;
}
r开发者_运维问答eturn 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;
}
The types:
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; }
}
I think you want:
var maquinasNoEncontradas = gruposCompletos
.SelectMany(g => g.Servidores)
.Select(x => x.Nombre)
.Concat(maquinasSeleccionadas)
.Where(x => !ContieneServidor(datosGruposServidores, x))
.ToList();
And then:
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);
}
You could potentially build the comma-separated version and then test whether that's an empty string... but I'm not sure I would, to be honest.
string.Join(", ", gruposCompletos
.SelectMany(x => x.Servidores)
.Select(x => x.Nombre)
.Concat(maquinasSeleccionadas)
.Where(x => !ContieneServidor(datosGruposServidores, x))
.ToArray());
精彩评论