C#Dynamic将所有属性投影到一个对象中

时间:2016-06-25 23:25:47

标签: linq c#-4.0 dynamic

我想将两个匿名对象的属性合并为一个。

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

我想在客户端ID上加入上述2个匿名对象,并使用obj和obj2中的所有道具创建对象。

var jn = (from i in obj
                join j in obj2 on i.ClientId equals j.ClientId
                select new
                {
                    i.*,j.*
                });

有没有办法通过动态或反射实现这一目标?我想我正在寻找一种通用的动态投影解决方案。

1 个答案:

答案 0 :(得分:1)

您可以使用反射将结果带入变量" jn"并将它们转换为Dictionary< string,object>。

修改您的linq表达式:

var jn = (from i in obj
    join j in obj2 on i.ClientId equals j.ClientId
    select new
    {
        i, j
    });

获取已连接类型的属性:

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

用法:

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

输出:

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

将字典转换为动态类型:

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

*注意:ExpandoObject继承自IDictionary&lt; string,object&gt;。您应该能够将动态对象强制转换为Dictionary&lt; string,object&gt;如果你想要/需要