Il problema qui è che Linq non sa che si desidera confrontare il Name
. Invece fa quello che fa per tutti i tipi di oggetti confronta l'hash che è diverso per due diverse istanze.
Quello che ti serve è dire al metodo dell'Unione come confrontare due elementi. È possibile farlo creando un numero personalizzato IEqualityComparer
che confronta due righe di dati nel modo desiderato.
Ecco un esempio di implementazione:
class CustomComparer : IEqualityComparer<DataRow>
{
#region IEqualityComparer<DataRow> Members
public bool Equals(DataRow x, DataRow y)
{
return ((string)x["Name"]).Equals((string)y["Name"]);
}
public int GetHashCode(DataRow obj)
{
return ((string)obj["Name"]).GetHashCode();
}
#endregion
}
Quando si chiama Union
è quindi necessario passare in un'istanza di questo operatore di confronto:
var comparer = new CustomComparer();
DataTable dtUnion = dt1.AsEnumerable()
.Union(dt2.AsEnumerable(), comparer).CopyToDataTable<DataRow>();
Vedi qui per maggiori info:
http://msdn.microsoft.com/en-us/library/bb358407.aspx
Parola di consulenza:
Linq è il migliore con le classi di dati personalizzate, che non lo è con lo standard DataRow
. È meglio avere una proprietà Name effettiva sulla classe, solo allora Linq può davvero brillare.
Se non si ha bisogno della flessibilità dello schema dinamico, si dovrebbe stare lontani da DataTable
e implementare classi personalizzate che assomigliano esattamente a ciò di cui si ha bisogno, dal momento che DataTable
è estremamente gonfio e lento.