我有一个主列表,其中包含我知道正确的数据库表的值:
masterList: List<string>(){ "business", "customer", "location", "employee", etc}
我已经查询了一个应该是相同的新数据库。我的测试将告诉我,我的团队为制作这个新数据库所做的脚本中是否有任何错误。 tablesList应该是我的查询的返回:
tablesList: List<string>(){ "business", "customer", "location", "employee", etc}
所以在实践中它们应该是相同的,但是为了测试错误,我想比较tablesList和masterList,以确保所有需要的表都在那里。作为此过程的副本,如果masterList上没有任何额外的表,我也会撤消搜索。
问题:如何将列表与主列表进行比较,并返回不匹配的项目?
我正在使用带有c#.net Core 2.0的Visual Studio 2017。
这是我到目前为止所做的尝试:
var errorsList = new List<string>();
tablesList = QuerySchemaForTables();
masterList = GrabMasterTableList();
foreach(var item in masterList)
errorsList.Add(tablesList.Where(x => x.Contains(item)));
但有了这个,我收到了错误:
无法从IEnumerable转换为字符串
答案 0 :(得分:2)
你在寻找类似的东西;
var errorList = tableList.Where(x => !masterList.Contains(x));
答案 1 :(得分:2)
您可以使用LINQ获取两个方向的错误。不需要循环:
var missingInMasterList = tableList.Where(x => !masterList.Contains(x)).ToList();
var missingInTableList = masterList.Where(x => !tableList.Contains(x)).ToList();
答案 2 :(得分:2)
您可以使用.Except()
IEnumerable
set operations之一来捕捉差异:
var missingTables = masterList.Except(tablesList);
var extraTables = tablesList.Except(masterList);
然后,要创建错误消息,您可以使用IEnumerables
将这些string.Join()
中的项目用逗号连接到一个字符串中:
var errorMessage = new StringBuilder();
if (missingTables.Any())
{
errorMessage.AppendLine("Missing Tables: " + string.Join(", ", missingTables));
}
if (extraTables.Any())
{
errorMessage.AppendLine("Extra Tables: " + string.Join(", ", extraTables));
}
然后,您可以通过检查errorMessage
的长度来输出结果,以确定是否遇到任何错误:
if (errorMessage.Length > 0)
{
Console.WriteLine(errorMessage.ToString());
}
else
{
Console.WriteLine("No extra or missing tables detected");
}
答案 3 :(得分:1)
要查找tablesList
但不在masterList
使用.Contains
中的所有项目:
var errorsList = tableList.Where(x => !masterList.Contains(x));
但我建议您使用HashSet<String>
masterList
,因此在O(1)
而不是O(n)
中搜索其中的项目:
var masterCollection = new HashSet<String>(GrabMasterTableList());
var errorsList = tableList.Where(x => !masterCollection.Contains(x));
至于您发布的代码问题:
foreach(var item in masterList)
errorsList.Add(tablesList.Where(x => x.Contains(item))); // <-- error
正如错误所指出的那样,Linq的.Where
返回IEnumerable<T>
而.Add
期望收集类型的单个项目,在这种情况下是{{1} }。您可以使用string
代替,但我认为更好地使用所有内容就是我上面写的内容。
答案 4 :(得分:1)
我认为最好使用Except()
如下
var MasterList = new List<string> { "business", "customer", "location", "employee"};
var ChildList = new List<String> { "customer", "location", "employee" };
var filter = MasterList.Except(ChildList);
这将是那些不在ChildList
中的值。您也可以反过来。
答案 5 :(得分:-1)
您的代码目前正在尝试将IEnumerable添加到List。
如果你想添加所有的匹配,你应该改为AddRange。
https://msdn.microsoft.com/en-us/library/z883w3dc(v=vs.110).aspx
var errorsList = new List<string>();
tablesList = QuerySchemaForTables();
masterList = GrabMasterTableList();
foreach(var item in masterList)
errorsList.AddRange(tablesList.Where(x => x.Contains(item)));