Reputation: 347
I want to Combine properties of two anonymous objects into one.
var obj = new[]
{
new {ClientId = 7, ClientName = "ACME Inc.", Jobs = 5},
new {ClientId = 8, ClientName = "JUST Inc.", Jobs = 25}
};
var obj2 = new[]
{
new {ClientId = 7, ClientAddress = "Gypsy Ave", ClientState = "KY"},
new {ClientId = 8, ClientAddress = "Dorky Rd", ClientState = "NC"}
};
I want to join the above 2 anonymous objects on client Id and create object with all props from obj and obj2.
var jn = (from i in obj
join j in obj2 on i.ClientId equals j.ClientId
select new
{
i.*,j.*
});
Is there a way to achieve this using dynamics or reflection? I think I'm looking for a generic dynamic projection kinda solution.
Upvotes: 0
Views: 1073
Reputation: 116
You can use reflection to take the results within the variable "jn" and convert them to Dictionary<string, object>.
Modify your linq expression:
var jn = (from i in obj
join j in obj2 on i.ClientId equals j.ClientId
select new
{
i, j
});
Get the properties of the joined type:
//Pass items within variable "jn"
private static Dictionary<string, object> joinLinqObjectProperties(object obj)
{
Dictionary<string, object> toReturn = new Dictionary<string, object>();
//This will be "i" and "j" from the linq select
var joinedObjectProperties = obj.GetType().GetProperties();
foreach (var prop in joinedObjectProperties)
{
var joinedObjectItem = prop.GetValue(obj, null);
//This will be the properties of the anonymous type
var subObjectProperties = joinedObjectItem.GetType().GetProperties();
foreach (var subProp in subObjectProperties)
{
if (!toReturn.ContainsKey(subProp.Name))
{
toReturn.Add(subProp.Name, subProp.GetValue(joinedObjectItem, null));
}
else
{
//Handle duplicate names
}
}
}
return toReturn;
}
Usage:
List<Dictionary<string, object>> results = new List<Dictionary<string, object>>();
foreach (var item in jn)
results.Add(joinLinqObjectProperties(item));
int iCount = 1;
foreach (var item in results)
{
Console.WriteLine(String.Format("Object {0}:", iCount));
foreach (var prop in item)
{
Console.WriteLine(String.Format("\tProperty: {0} = {1}", prop.Key, prop.Value));
}
Console.WriteLine();
iCount++;
}
Output:
Object 1:
Property: ClientId = 7
Property: ClientName = ACME Inc.
Property: Jobs = 5
Property: ClientAddress = Gypsy Ave
Property: ClientState = KY
Object 2:
Property: ClientId = 8
Property: ClientName = JUST Inc.
Property: Jobs = 25
Property: ClientAddress = Dorky Rd
Property: ClientState = NC
To convert a Dictionary to a dynamic type:
private static dynamic dictionaryToDynamic(Dictionary<string, object> dictionary)
{
dynamic result = new ExpandoObject();
var resAsIDic = result as IDictionary<string, object>;
foreach (var key in dictionary.Keys)
resAsIDic[key] = dictionary[key];
return result;
}
https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx
*Note: The ExpandoObject inherits from IDictionary<string, object>. You should be able to cast the dynamic object back to Dictionary<string, object> if you want/need
Upvotes: 1