The problem is that Linq does not know that you want to compare Name
. Instead, it does what it does for all types of objects, it compares a hash that is different for two different instances.
What you need todo is to tell the Union method how to compare the two elements. You can do this by creating a custom IEqualityComparer
that compares two rows of data the way you want it.
Here is an example implementation:
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 }
When calling Union
you need to pass an instance of this comparator:
var comparer = new CustomComparer(); DataTable dtUnion = dt1.AsEnumerable() .Union(dt2.AsEnumerable(), comparer).CopyToDataTable<DataRow>();
See here for more information:
http://msdn.microsoft.com/en-us/library/bb358407.aspx
Tip: Linq is best for custom data classes, but DataRow
is not. It is better to have the actual Name property in the class, only then Linq can really shine.
If you don't want the flexibility of a dynamic schema, you should stay away from the DataTable
and implement custom classes that resemble exactly what you need, since the DataTable
extremely bloated and slowed down.
source share