c# - rimen - nombres para niños 2018
Linq Distinct() por nombre para completar una lista desplegable con nombre y valor (7)
Estoy tratando de completar una lista desplegable con compañías farmacéuticas, como Bayer, Medley, etc. Y obtengo estos nombres de DB y estos nombres se repiten en DB, pero con diferentes id.
Estoy intentando usar Linq Distinct (), pero no quiero usar el comparador de igualdad. ¿Hay otra manera?
Mi lista desplegable se debe completar con la identificación y el nombre de la empresa.
Estoy intentando algo así como:
var x = _partnerService
.SelectPartners()
.Select(c => new {codPartner = c.codPartner, name = c.name})
.Distinct();
Esto muestra compañías repetidas en ddl.
¡Gracias!
Distinc usará GetHashCode si no lo dice (a través de un IEqualityComparer) para usar otro método. Podría usar un equalcomparer genérico, como este:
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
private Func<T, T, Boolean> comparer;
public GenericEqualityComparer(Func<T, T, Boolean> comparer)
{
this.comparer = comparer;
}
#region IEqualityComparer<T> Implementation
public bool Equals(T x, T y)
{
return comparer(x, y);
}
public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
#endregion
}
y luego usar así (kindof)
public static IEqualityComparer<YourType> MyComparer
{
get
{
return new GenericEqualityComparer<YourType>((x, y) =>
{
return x.name.Equals(y.name);
});
}
}
Distintivo funciona en todo el select. Si incluye c.codPartner en la selección, y hay dos valores diferentes de c.codPartner para el mismo c.nombre, verá dos filas con el mismo c.nombre.
La siguiente expresión seleccionará solo compañías distintas y devolverá la primera ocurrencia con su id.
partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First());
No creo que puedas hacer esto con una clase anónima, pero si creaste un objeto de datos como
class Foo
{
private int _ID;
public int ID
{
get { return _ID; }
set { _ID = value; }
}
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
podrías crear un objeto comparador como
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Name == y.Name;
}
public int GetHashCode(Foo obj)
{
return obj.GetHashCode();
}
}
Si no especifica un parámetro IEqualityComparer, solo usará Object.ReferenceEquals, que observa el valor GetHashKey de los objetos. Para tipos anónimos, son únicos.
Ahora resolver esto es un poco complicado, ya que no puedes escribir un IEqualityComparer para un tipo anónimo. Entonces creas un tipo real para el problema:
class Partner
{
public int codPartner {get; set;}
public string name {get; set;}
public override int GetHashCode() { return name .GetHashCode();}
}
var x = _partnerService.SelectPartners()
.Select(c => new Partner {codPartner = c.codPartner, name = c.name})
.Distinct();
simplemente pase en su propio comparador al método Distinct usando una de las otras sobrecargas.
(extension) IQueryable<T> IQueryable<T>.Distinct( IEqualityComparer<T> comparer )
var distinctCompanies = Companies
.GroupBy(c => c.CompanyName)
.Select(g => g.First());