1

I have a StudentData class

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; }
}

Each student has a unique Id that identifies him

I have a List<StudentData> CurrentData that has data of

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

I then have a List<StudentData> DataToUpdate which only contains the Id and Marks fields. Not the other fields.

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

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

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

The Ids of the list are not necessary in the same order

If you compare the two lists only Peter Parker's marks have changed in one subject.

I want to get the output to return

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

I want to takeList<StudentData> CurrentData inner join this with List<StudentData> DataToUpdate but only where marks are different

So in SQL it want the following

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
)

How do I do the above in LINQ?

In the Linq select how do I take all properties from CurrentData but include the 3 Subject properties from DataToUpdate in it to give me List<ChangedData>?

I could map each and every property but my StudentData has 100 fields and I would prefer to have something like

select new StudentData {
    this=CurrentData,
    this.Subject1Mark=DataToUpdate.Subject1Mark,
    this.Subject2Mark=DataToUpdate.Subject2Mark,
    this.Subject3Mark=DataToUpdate.Subject3Mark,
}

but I'm not sure how to write this

There is an answer in another stackoverflow question which should work but it doesn't. If I implement that solution (I simplify the example for simplicity)

        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; })
             ;

but the above x.cd.Subject1Mark isn't updated by x.ld.Subject1Mark although I use the answer in the linked stackoverflow question

Community
  • 1
  • 1
dfmetro
  • 4,462
  • 8
  • 39
  • 65

1 Answers1

1

The structure of LINQ query looks very similar to 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
    };

The main difference is that filtering out by inequality has moved from the on clause in SQL to a where clause of LINQ.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • In the `select` how do I take all properties from `cur` but include the 3 Subject properties from `upd` in it? – dfmetro Feb 08 '16 at 20:17
  • Problem is I need the output to be of type List because I need to write it to the database using the original object type. If I make it like in your answer I get error `Cannot convert IEnumerable anonymous type to Generic.List – dfmetro Feb 08 '16 at 20:30
  • @devc2 You can't produce `StudentData` from `{StudentData+three more fields}`, unless you would like to replace the old data with whatever is in the `upd`, in which case you do `select new StudentData {Id=cur.Id, FirstName=cur.FirstName, ..., UpdatedSubject1Mark = upd.UpdatedSubject1Mark, UpdatedSubject2Mark = upd.UpdatedSubject3Mark, ...}` – Sergey Kalinichenko Feb 08 '16 at 20:46