比较两个不同类列表中的单个属性



过去两天我一直在阅读如何做到这一点,但我仍然不明白如何做到这一点。

目标:"现有数据库引擎"比较列表"新Excel电机"列表仅通过比较每个列表的name属性。我不想比较任何其他属性。返回一个仅对"现有数据库引擎"唯一的对象列表。

这是我想做的事情的简化版本:

自定义类:

public class motor_Excel
{
public string MotorName; //the field I need to be able to compare with motor_Database.iName
public string MotorVoltage;
public double MotorHP;
}
public class motor_Database
{
public int iID;
public string iName; //the field I need to be able to compare with motor_Excel.MotorName
public int iCircuit;
}

列出这些自定义类:

List<motor_Database> equipList_EX = ReadDatabase(DBpath.txt); //create new custom obj list of from database
List<motor_Excel> equipList_Update = ReadExcel(Excelpath.txt); //create new custom obj list of from excel

我想返回这样的东西(我知道这不会工作,除了";只接受泛型):

List<motor_Database> result = equipList_EX.iName.Except(equipList_Update.MotorName)

我相信我有4个选择:

选项1:使用LINQ "Where:
选项2:使用扩展方法
选项3:LINQ Except with custom IEqualityComparer
选项4:Enumerable。SequenceEqual(list1, list2)


我一直有这么多的麻烦。我在努力学习LINQ, Except, eququalitycompare等是如何工作的。我开始觉得自己很笨,我从来没有觉得自己这么无能。我是c#的新手,而且我甚至很难理解ms .关于这些东西的文档。我不知道怎么读Enumerable。除了方法文档。API文档是我以前从未见过的……如果您有什么建议,告诉我如何学习如何阅读这些类/方法的文档,我将不胜感激。

请从基本层面解释为什么except不起作用。我很困惑。

您感到困惑的原因是因为您正在查看API参考,而不是LINQ的文档。对于任何语言,任何API,你都会遇到同样的问题。

赋值文本没有提到多个类:

"现有数据库引擎"比较列表;"新Excel电机"列表通过比较每个列表的name属性。

如果你比较的是Motor对象,你只需要一个Motor类。在这个例子中,你只比较名字。您正在检查查找名称没有出现在新电机名称列表中的Motor对象。

Except在这里没有用。如描述所示:

生产两个序列的集合差。

这不是废话。就像SQL的EXCEPT一样,这两个集合的类型/形状必须相同。这就是为什么该方法只对相同类型的项有效。

你想要的可以用WhereList<string>.Contains

List<Motor> motors=ReadDatabase(DBpath.txt); 
List<string> new_names=ReadExcel(...);
var old_motors=motors.Where(m=>!new_names.Contains(m.Name))
.ToList();

如果使用HashSet

可以加快速度
...
var names_set=new HashSet<string>(new_names);
var old_motors=motors.Where(m=>!names_set.Contains(m.Name))
.ToList();

如果我理解正确的问题,你不能只是过滤数据库汽车通过比较每一个的名字到excel电动机名称列表,并返回没有匹配的条目吗?

List<motor_Database> dbMotors = ReadDatabase(DBpath.txt); 
List<motor_Excel> xlMotors = ReadExcel(Excelpath.txt);
List<motor_Database> uniqueDbMotors = dbMotors
.Where(dbMotor => xlMotors.All(xlMotor => xlMotor.MotorName != dbMotor.iName))
.ToList();

同样,在您的"选项"列表中,您使用了一个简单的for循环。上面的代码可以写成:

var uniqueDbMotors = new List<motor_Database>();
foreach(var dbMotor in dbMotors)
{
var foundMatch = false;
foreach (var xlMotor in xlMotors)
{
if (dbMotor.iName == xlMotor.MotorName)
{
foundMatch = true;
break;
}
}
if (!foundMatch) uniqueDbMotors.Add(dbMotor);
}

您也可以使用"LEFT JOIN"对于这样的任务:

List<motor_Database> result = 
(from ex in equipList_EX
join up in equipList_Update on ex.iName equals up.MotorName into gj
from up in gj.DefaultIfEmpty()
where up == null
select ex).ToList();