1

我有两个 DataTables 从两个不同的来源获取数据。我想要一个新的 DataTable Table3,其中只有没有匹配 Table2 行的 Tables1 行。我的两个数据表具有不同的结构,如下所示。但是,它们都共享相同的主键 - CarReg。因此,我想使用 CarReg 列比较行并返回 Table1 中但不在 Table2 中的所有行。我返回的 Table3 DataTable 将具有与 Table1 相同的结构。

Table1.Columns.Add("CarReg", typeof(string));
Table1.Columns.Add("Site", typeof(string));
Table1.Columns.Add("Route", typeof(double));
Table1.Columns.Add("Driver", typeof(string));
Table1.Columns.Add("StartingDate", typeof(string));

Table2.Columns.Add("CarReg", typeof(string));
Table2.Columns.Add("SITE DESC", typeof(string));
Table2.Columns.Add("Route DESC", typeof(double));
Table2.Columns.Add("Driver", typeof(string));
Table2.Columns.Add("KILOS", typeof(string));

我已经尝试过以下方法,但是,我从第一个表 Table1 中获取所有记录。我只需要获取 Table1 中但不在 Table2 中的记录。因此,例如,如果 Table1 有 20 条记录,Tables2 有 15 条记录,我只需要 5 条记录。请帮忙。

var recordsNotInB = TableA.AsEnumerable().Select(r =>r.Field<string>("CarReg").Except(TableB.AsEnumerable().Select(r => r.Field<string>("CarReg")));
4

4 回答 4

1

在不知道您的代码的情况下,我会想出这个。

var idsFromTableB = TableB.AsEnumerable().Select(tb => tb.Field<string>("CarReg"));
var recordsNotInB = TableA.AsEnumerable().Where(ta => !idsFromTableB.Contains(ta.Field<string>("CarReg")));
于 2017-03-01T11:06:17.590 回答
1

您可以提高性能,还可以使用哈希集指定比较方法。

var idsFromTableB = new HashSet<string>(TableB.AsEnumerable()
    .Select(tb => tb.Field<string>("CarReg")), StringComparer.OrdinalIgnoreCase);

var recordsNotInB = TableA.AsEnumerable()
    .Where(ta => !idsFromTableB.Contains(ta.Field<string>("CarReg")));
于 2017-03-01T11:42:55.690 回答
0

好的,这是一个冗长的解决方案,但我已经对其进行了测试并且它有效。

我已经通过为每个 Table 创建 POCO 对象来完成它,然后将差异视为使用公共属性比使用容易出错的 Table1["CarReg"] 更容易玩。

可能有人可以改进这个解决方案。

让您的表由 POCO 类表示,例如:

public class Table1
{
    public string CarReg { get; set; }
    public string Site { get; set; }
    public double Route { get; set; }
    public string Driver { get; set; }
    public string DateString { get; set; }
}

public class Table2
{
    public string CarReg { get; set; }
    public string Site { get; set; }
    public double Route { get; set; }
    public string Driver { get; set; }
    public string Kilos { get; set; }
}

让我们填充数据:

IEnumerable<Table1> data1 = new List<Table1>()
            {
                new Table1() { CarReg = "123ABC", DateString = "20/02/2018", Driver = "Driver 1", Route = 45.45, Site = "England" },
                new Table1() { CarReg = "456ABC", DateString = "20/03/2018", Driver = "Driver 2", Route = 55.45, Site = "Scotland" },
                new Table1() { CarReg = "789ABC", DateString = "20/04/2018", Driver = "Driver 3", Route = 65.45, Site = "Wales" },
            };

            IEnumerable<Table2> data2 = new List<Table2>() {
                new Table2() { CarReg = "123XYZ", Kilos = "34KG", Driver = "Driver 5", Route = 45.45, Site = "Karachi" },
                new Table2() { CarReg = "456ABC", Kilos = "44KG", Driver = "Driver 2", Route = 55.45, Site = "Scotland" },
                new Table2() { CarReg = "789CCC", Kilos = "54KG", Driver = "Driver 7", Route = 65.45, Site = "Hyderabad" },
            };

创建一个列表来保存结果数据:

 List<Table1> oneList = new List<Table1>();

循环识别不在 Table2 中的行

  bool matchFound = false; // an indicator if match is found in table 2

        foreach (var item in data1)
        {
            foreach (var item2 in data2)
            {
                if (item.CarReg != item2.CarReg)
                {
                    matchFound = false;
                }
                else
                {
                    matchFound = true;
                    break;
                }
            }
            if (!matchFound)
            {
                if (!oneList.Contains(item))
                {
                    oneList.Add(item);
                }
            }

        }

希望这有帮助!

于 2017-03-01T12:35:07.857 回答
0

您可以使用下一个代码片段进行尝试:

        var result = new List<DataRow>();
        //convert to list to avoid multiple enumerations
        var table2List = Table2.AsEnumerable().ToList();

        foreach(var row in Table1.AsEnumerable())
        {
            var matchingRow = table2List.FirstOrDefault(x => x["CarReg"] == row["CarReg"]);

            if(matchingRow == null)
            {
                result.Add(row);
            }
        }  

您应该根据 CarReg 字段从 Table1 中获取不在 Table2 中的 DataRows 集合。

于 2017-03-01T11:25:01.117 回答