Sort and merge list based on another list Here I'm merging a list to end of another list after sorting it according to another list.This should sort processdetails list according to the order in routeplans list if any item not present in processdetails list is found it should keep the order and add it to processdetails list. Simply saying it just merging two lists based on another list.The below code works fine, I want to know whether there is cleaner way of doing this.if possible in linq.

using System;
using System.Collections.Generic; 
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SortByList
{
public class OnGoingProcess
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Code { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var processDetails = new List&lt;OnGoingProcess&gt;();
        processDetails.Add(new OnGoingProcess() { Id = 120, Name = "Process 29", Code = "T20" });
        processDetails.Add(new OnGoingProcess() { Id = 100, Name = "Process 2", Code = "A20" });
        processDetails.Add(new OnGoingProcess() { Id = 99, Name = "Process 3", Code = "S20"  });
        processDetails.Add(new OnGoingProcess() { Id = 85, Name = "Process 229", Code = "B20" });
        processDetails.Add(new OnGoingProcess() { Id = 220, Name = "Process 39", Code = "C20" });
        processDetails.Add(new OnGoingProcess() { Id = 15, Name = "Process 20", Code = "D20" });
        processDetails.Add(new OnGoingProcess() { Id = 101, Name = "Process 129", Code = "G20" });

        var routePlans = new List&lt;OnGoingProcess&gt;();
        routePlans.Add(new OnGoingProcess() { Id = 100, Name = "Process 2" });
        routePlans.Add(new OnGoingProcess() { Id = 120, Name = "Process 29" });
        routePlans.Add(new OnGoingProcess() { Id = 222, Name = "Process new" });
        routePlans.Add(new OnGoingProcess() { Id = 85, Name = "Process 229" });
        routePlans.Add(new OnGoingProcess() { Id = 101, Name = "Process 129" });

        var sortedPlans = new List&lt;OnGoingProcess&gt;();

        foreach (var plan in routePlans)
        {
            var selectedDetails = processDetails.Where(x =&gt; x.Id == plan.Id).ToList();

            if (selectedDetails.Any())
            {
                sortedPlans.AddRange(selectedDetails);
                processDetails.RemoveAll(x =&gt; x.Id == plan.Id);

            }
            else
            {
                sortedPlans.Add(plan);
            }
        }
        processDetails.AddRange(sortedPlans);

        foreach (var sorted in processDetails)
        {
            Console.WriteLine("Id : " + sorted.Id + " Name : " + sorted.Name + " Code : " + sorted.Code );
        }

        Console.ReadKey();

     //Id : 99 Name : Process 3 Code : S20
     //Id : 220 Name : Process 39 Code : C20
     //Id : 15 Name : Process 20 Code : D20
     //Id : 100 Name : Process 2 Code : A20
     //Id : 120 Name : Process 29 Code : T20
     //Id : 222 Name : Process new Code :
     //Id : 85 Name : Process 229 Code : B20
     //Id : 101 Name : Process 129 Code : G20

    }
}
}
Very poor problem statement.  Problem statement is based on your perceived solution so review is difficult.  I could only figure out what you are trying to do by reviewing the code.  

Why long Id? If you have that many OnGoingProcess then will probably need a different approach.

Have proper constructors for OnGoingProcess and make Id read only.  

Create a proper application and test.  Don't just jam everything in Main.

You are changing selectedDetails.   A calling procedure does not want an input changed.   Output a new List mergedDetails.

Proper problem statement
processDetails and sortedPlans are each List of OnGoingProcess identified by property Id
Need output in this order    


processDetails not present in sortedPlans (in the order in    processDetails)
sortedPlans (in the order of sortedPlans)
if present in processDetails then processDetails
else then sorted plan  


Putting those thoughts in action 

public static void OnGoingProcessMergeTest()
{
    var processDetails = new List&lt;OnGoingProcess&gt;()
    { new OnGoingProcess(120, "Process 29", "T20"), new OnGoingProcess(100, "Process 2", "A20"), new OnGoingProcess(99, "Process 3", "S20"),
      new OnGoingProcess(85, "Process 229", "B20"), new OnGoingProcess(220, "Process 39", "C20"), new OnGoingProcess(15, "Process 20", "D20"),
      new OnGoingProcess(101, "Process 129", "G20")};

    var routePlans = new List&lt;OnGoingProcess&gt;()
    { new OnGoingProcess(100, "Process 2"), new OnGoingProcess(120,"Process 29"), new OnGoingProcess(222, "Process new"),
      new OnGoingProcess(85, "Process 229"), new OnGoingProcess(101, "Process 129")};

    List&lt;OnGoingProcess&gt; mergedDetails = OnGoingProcessMerge2(processDetails, routePlans);
    foreach (var sorted in mergedDetails)
    {
        Debug.WriteLine("Id : " + sorted.Id + " Name : " + sorted.Name + " Code : " + sorted.Code);
    }
    Debug.WriteLine("");
}       
public static List&lt;OnGoingProcess&gt; OnGoingProcessMerge2(List&lt;OnGoingProcess&gt; processDetails, List&lt;OnGoingProcess&gt; routePlans)
{
    List&lt;OnGoingProcess&gt; onGoingProcessMerge = processDetails.Where(x =&gt; !(routePlans.Any(y =&gt; y.Id == x.Id))).ToList();
    foreach(OnGoingProcess routePlan in routePlans)
    {
        OnGoingProcess processDetail = processDetails.FirstOrDefault(x =&gt; x.Id == routePlan.Id);
        onGoingProcessMerge.Add(processDetail ?? routePlan);
    }
    return onGoingProcessMerge;
}