hello world hello world - 3 months ago 14
C# Question

Combine 2 lists with having common object value c#

I have two custom lists.

public class Model1
{
public string EmpGuid { get; set; }
public string EmployeeName { get; set; }
public DateTime Birthdate { get; set; }

}

public class Model2
{
public string EmpGuid { get; set; }
public string EmployeeName { get; set; }
public DateTime Anniversary{ get; set; }

}


Now I create 2 lists from these classes like so :-

var List1 = new List<Model1>();
var List2 = new List<Model2>();


In my Model classes the values for EmpGuid is unique and is the same in both lists. Now I want to create one single class with the following properties

public class Model3
{
public string EmpGuid { get; set; }
public string EmployeeName { get; set; }
public DateTime Birthdate { get; set; }
public DateTime Anniversary{ get; set; }
}


Here I want to combine both the list ie. List1 and List 2 grouping them with the EmpGuid such that I have a single List of type List where I have the Birthday and anniversary for each EmpGuid.

The final output should be :-

EDIT

List 1 - EmpGuid - abc
EmpName - emp1
Birthday - something

EmpGuid - xyz
EmpName - emp2
Birthday - something2

List 2 - EmpGuid - abc
EmpName - emp1
Anniversary - somethingAnniversary

EmpGuid - mno
empName - emp3
Anniversary - somethingAnniversary3

List3 - EmpGuid - abc
EmpName - emp1
Birthday - something
Anniversary - somethingAnniversary

EmpGuid - xyz
EmpName - emp2
Birthday - something2
Anniversary - null


EmpGuid - mno
EmpName - emp3
Birthday - null
Anniversary - somethingAnniversary3


How can I achieve this?

Any help is appreciated

Answer

You can do this by using LINQ's Join method:

var List3 = List1.Join(List2, l1 => l1.EmpGuid, l2 => l2.EmpGuid, 
                    (l1, l2) => new Model3 {
                             EmpGuid = l1.EmpGuid,
                             EmployeeName = l1.EmployeeName,
                             BirthDate = l1.BirthDate,
                             Anniversary = l2.Anniversary}).ToList();

This combines the two lists by comparing the EmpGuids and creates for each combination a new Model3 instance.

One problem is that you said the EmployeeName can be different, so you have to decide which one you take or how you combine them.


Unfortunatly there is no full outer join in LINQ, so you will need to this a little more manually. One possibility is to add the missing elements after the above query like this:

List3.AddRange(List1.Where(l1 => List2.All(l2 => l1.EmpGuid != l2.EmpGuid)
                    .Select(l1 => new Model3 {
                         EmpGuid = l1.EmpGuid,
                         EmployeeName = l1.EmployeeName,
                         BirthDate = l1.BirthDate,
                         Anniversary = null}));

and the same the other way around:

List3.AddRange(List2.Where(l2 => List1.All(l1 => l1.EmpGuid != l2.EmpGuid)
                    .Select(l2 => new Model3 {
                         EmpGuid = l2.EmpGuid,
                         EmployeeName = l2.EmployeeName,
                         Anniversary = l2.Anniversary}));

This takes all elements from the one list with GUIDs that don't appear in the second list and creates the appropriate Model3 instances. (Note that DateTime is a value type and cannot be null, by default it's DateTime.MinValue).

Comments