0

I have two expando objects and these are completely dynamic. These would be generated at runtime. Now I want to Join these objects by finding the common property.

Kindly check below code for further information

    List<dynamic> object1 = 
   [{id : 10, name : "sai" age : 22},
    {id : 20, name : "ram" age : 12},
    {id : 30, name : "sony" age : 42},
    {id : 40, name : "sunny" age : 25},
    {id : 50, name : "bobby" age : 29},
    {id : 60, name : "lucky" age : 18}]
    List<dynamic>object2 = 
[{id : 10, company: "xyz" salary : 52133},
{id : 30, company: "abc" salary : 12345},
{id : 40, company: "mno" salary : 26859},
{id : 60, company: "xyz" salary : 96523}]

I want to join these two objects base on common key, i.e.; Id

Can you please help me to find common property in both objects and join both objects such that the result will be

[{id : 10, name : "sai" age : 22, company: "xyz" salary : 52133},
{id : 20, name : "ram" age : 12},
{id : 30, name : "sony" age : 42, company: "abc" salary : 12345},
{id : 40, name : "sunny" age : 25, company: "mno" salary : 26859},
{id : 50, name : "bobby" age : 29},
{id : 60, name : "lucky" age : 18, company: "xyz" salary : 96523}]

thanks in advance.

  • Update :

List Result = map(result, result1, referenceKey);

    private dynamic map(List<ExpandoObject> result, List<ExpandoObject> result1, string referenceKey)
        {
            var Result = from x in result
                         join y in result1 on ((IDictionary<string, object>)x)[referenceKey] equals ((IDictionary<string, object>)y)[referenceKey] into yg
             from y in yg.DefaultIfEmpty()
             select new { x,y};

            List<dynamic> list = new List<dynamic>();
foreach (var entry in Result)
{
    dynamic itemToAdd = new ExpandoObject();

    var expandoX = ToDynamic(entry.x);
    var dictX = expandoX as IDictionary<string, object>;
    if(dictX != null)
    {
        foreach (KeyValuePair<string, object> e in dictX)
        {
            var dictO = itemToAdd as IDictionary<string, object>;
            if(!dictO.ContainsKey(e.Key))
                dictO.Add(e.Key, e.Value);
        }
    }

    if (entry.y != null)
    {
        var expandoY = ToDynamic(entry.y);
        var dictY = expandoY as IDictionary<string, object>;
        if(dictY != null)
        {
            foreach (KeyValuePair<string, object> e in dictY)
            {
                var dictO = itemToAdd as IDictionary<string, object>;
                if(!dictO.ContainsKey(e.Key))
                    dictO.Add(e.Key, e.Value);
            }
        }
    }

    list.Add(itemToAdd);
}

return list;
        }
        public dynamic ToDynamic(object value)
        {
            IDictionary<string, object> expando = new ExpandoObject();

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
                expando.Add(property.Name, property.GetValue(value));

            return expando as ExpandoObject;
        }
satish kumar V
  • 1,695
  • 6
  • 33
  • 47

1 Answers1

1

Something like that?

var result = from x in object1
             join y in object2 on x.id equals y.id into yg
             from y in yg.DefaultIfEmpty()
             select new { x,y};


List<dynamic> list = new List<dynamic>();
foreach (var entry in result)
{
    if (entry.y != null)
    {
        list.Add(new {entry.x.id, entry.x.name, entry.x.age, entry.y.company, entry.y.salary });
    }
    else
    {
        list.Add(new {entry.x.id, entry.x.name, entry.x.age});                    
    }
}

UPDATE: To be rather dynamic with your properties you need following extension method:

public static dynamic ToDynamic(this object value)
{
    IDictionary<string, object> expando = new ExpandoObject();

    foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
        expando.Add(property.Name, property.GetValue(value));

    return expando as ExpandoObject;
}

then you can add the properties dynamically to a List of dynamic items (leave the linq join as it is):

List<dynamic> list = new List<dynamic>();
foreach (var entry in result)
{
    dynamic itemToAdd = new ExpandoObject();

    var expandoX = Extensions.ToDynamic(entry.x);
    var dictX = expandoX as IDictionary<string, object>;
    if(dictX != null)
    {
        foreach (KeyValuePair<string, object> e in dictX)
        {
            var dictO = itemToAdd as IDictionary<string, object>;
            if(!dictO.ContainsKey(e.Key))
                dictO.Add(e.Key, e.Value);
        }
    }

    if (entry.y != null)
    {
        var expandoY = Extensions.ToDynamic(entry.y);
        var dictY = expandoY as IDictionary<string, object>;
        if(dictY != null)
        {
            foreach (KeyValuePair<string, object> e in dictY)
            {
                var dictO = itemToAdd as IDictionary<string, object>;
                if(!dictO.ContainsKey(e.Key))
                    dictO.Add(e.Key, e.Value);
            }
        }
    }

    list.Add(itemToAdd);
}

so... there's just 3 things you must know: id is your key to join and there's two entities x and y.

stefankmitph
  • 3,236
  • 2
  • 18
  • 22