我有两个DataTable从两个不同的来源获取数据。我想要一个新的DataTable Table3,其中只有TABLE1行没有匹配的Table2行。我的两个DataTable具有不同的结构,如下所示。但是,它们都共享相同的主键 - 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")));
答案 0 :(得分:1)
如果您不再了解您的代码,我会想出这个。
var idsFromTableB = TableB.AsEnumerable().Select(tb => tb.Field<string>("CarReg"));
var recordsNotInB = TableA.AsEnumerable().Where(ta => !idsFromTableB.Contains(ta.Field<string>("CarReg")));
答案 1 :(得分: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")));
答案 2 :(得分: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);
}
}
您应该从Table1获取基于CarReg字段的不在Table2中的DataRows集合。
答案 3 :(得分:0)
好的,这是一个冗长的解决方案,但我已经测试过它并且有效。
我已经通过为每个表创建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);
}
}
}
希望这有帮助!