请你检查一下这里有什么问题.
我需要联合这个,但它返回6个记录而不是5个(因为"Amir"出现两次)
DataTable dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("Name"));
dt1.Rows.Add(dt1.NewRow()["Name"] = "Imran");
dt1.Rows.Add(dt1.NewRow()["Name"] = "Amir");
dt1.Rows.Add(dt1.NewRow()["Name"] = "Asif");
DataTable dt2 = new DataTable();
dt2.Columns.Add(new DataColumn("Name"));
dt2.Rows.Add(dt2.NewRow()["Name"] = "Tandulkar");
dt2.Rows.Add(dt2.NewRow()["Name"] = "Amir");
dt2.Rows.Add(dt2.NewRow()["Name"] = "Sheqwag");
DataTable dtUnion = dt1.AsEnumerable()
.Union(dt2.AsEnumerable()).CopyToDataTable<DataRow>();
Run Code Online (Sandbox Code Playgroud)
ntz*_*lis 10
这里的问题是Linq不知道你想要比较Name.相反,它会对所有对象类型执行的操作,它会比较两个不同实例的哈希值.
您需要的是告诉Union方法如何比较两个项目.您可以通过创建以IEqualityComparer您希望的方式比较两个数据行的自定义来实现此目的.
这是一个示例实现:
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
}
Run Code Online (Sandbox Code Playgroud)
在打电话给Union你时,需要传入这个比较器的一个实例:
var comparer = new CustomComparer();
DataTable dtUnion = dt1.AsEnumerable()
.Union(dt2.AsEnumerable(), comparer).CopyToDataTable<DataRow>();
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅此处:http:
//msdn.microsoft.com/en-us/library/bb358407.aspx
建议:
Linq最适合定制数据类,但DataRow不是.最好在课堂上有一个实际的Name属性,只有Linq才能真正发光.
如果您不需要动态模式的灵活性,您应该远离DataTable并实现类似于您所需的自定义类,因为DataTable它非常臃肿和缓慢.