DataTable Union

Ali*_*Ali 8 c# linq datatable

请你检查一下这里有什么问题.

我需要联合这个,但它返回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它非常臃肿和缓慢.