如何匹配两个列表只与Linq中不同的项目匹配

时间:2016-02-08 20:05:04

标签: linq

我有StudentData

public class StudentData
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public int? Bonus { get; set; }
    public int? Subject1Mark { get; set; }
    public int? Subject2Mark { get; set; }
    public int? Subject3Mark{ get; set; }
}

每个学生都有一个独特的Id来识别他

我有List<StudentData> CurrentData,其数据为

  

1,John,Smith,10,50,50,50

     

2,Peter,Parker,10,60,60,60

     

3,Sally,Smart,10,70,70,70

     

4,Danny,Darko,20,80,80,80

然后我有List<StudentData> DataToUpdate,其中只包含Id和标记字段。不是其他领域。

  

1,null,null,null,50,50,50

     

2,null,null,null,65,60,60

     

3,null,null,null,70,70,70

列表的ID不需要按相同的顺序

如果比较两个列表,只有Peter Parker的标记在一个主题中发生了变化。

我想让输出返回

  

2,Peter,Parker,10,65,60,60

我想将List<StudentData> CurrentData内部加入List<StudentData> DataToUpdate,但仅限于标记不同的地方

所以在SQL中它需要以下

SELECT
CurrentData.Id,
CurrentData.FirstName ,
CurrentData.Surname,
CurrentData.Bonus,
DataToUpdate.Subject1Mark,
DataToUpdate.Subject2Mark,
DataToUpdate.Subject3Mark
FROM CurrentData
INNER JOIN DataToUpdate
ON CurrentData.Id= DataToUpdate.Id
AND (
    CurrentData.Subject1Mark<> DataToUpdate.Subject1Mark
    OR
    CurrentData.Subject2Mark<> DataToUpdate.Subject2Mark
    OR
    CurrentData.Subject3Mark<> DataToUpdate.Subject3Mark
)

如何在LINQ中执行上述操作?

在Linq select中如何从CurrentData中获取所有属性,但是在其中包含DataToUpdate中的3个主题属性,以便为我提供List<ChangedData>

我可以映射每个属性,但我的StudentData有100个字段,我更喜欢像

这样的东西
select new StudentData {
    this=CurrentData,
    this.Subject1Mark=DataToUpdate.Subject1Mark,
    this.Subject2Mark=DataToUpdate.Subject2Mark,
    this.Subject3Mark=DataToUpdate.Subject3Mark,
}

但我不确定如何写这个

在另一个stackoverflow question中有一个答案应该有效,但事实并非如此。如果我实现了该解决方案(为简单起见,我简化了示例)

        var changedData = currentData
             .Join(dataToUpdate, cd => cd.Id, ld => ld.Id, (cd, ld) => new { cd, ld })
             .Select(x => { x.cd.Subject1Mark= x.ld.Subject1Mark; return x.cd; })
             ;

但上述x.cd.Subject1Mark并未由x.ld.Subject1Mark更新,尽管我在链接的stackoverflow问题中使用了答案

1 个答案:

答案 0 :(得分:1)

LINQ查询的结构与SQL非常相似:

var res =
    from cur in CurrentData
    join upd in DataToUpdate on upd.Id equals cur.Id
    where (cur.Subject1Mark != upd.Subject1Mark || cur.Subject2Mark != upd.Subject2Mark || cur.Subject3Mark != upd.Subject3Mark)
    select new {
        Current = cur
    ,   UpdatedSubject1Mark = upd.Subject1Mark
    ,   UpdatedSubject2Mark = upd.Subject2Mark
    ,   UpdatedSubject3Mark = upd.Subject3Mark
    };

主要区别在于,按不等式过滤已从SQL中的on子句转移到LINQ的where子句。