LINQ - 选择类的列表作为类成员的字段

时间:2013-06-14 16:57:44

标签: c# linq

例如,我有这些课程:

public class Person{  
  public string name, surname;  
  public int age;  
  public List<Aspect> aspect; 
}

public class Aspect
{
    public string key;
    public string value;
}

我想要LINQ表达式在对象中显示这样的数据:

NAME, SURNAME, ASPECT1.KEY, ASPECT2.KEY, ...

换句话说,LINQ表达式返回一个对象列表,如:

[0]{name="exampleName1", surname="surname1", age="age1", aspectKey1 = "aspectValue11", aspectKey2 = "aspectValue2", ...}
[1]{name="exampleName2", surname="surname2", age="age2", aspectKey1 = "aspectValue12", aspectKey2 = "aspectValue22", ...}

这可以通过LINQ选择吗?

1 个答案:

答案 0 :(得分:9)

您可以使用以下内容:

string ReportPerson(Person person)
{
    return string.Format("{0}, {1}, {2}", person.name, person.surname,
        string.Join(", ", person.aspect.SelectMany(a => new[] {a.key, a.value})));
}

编辑以响应您的修改:

这不可能直接实现,因为匿名类型是在编译时定义的。构建一系列这样的属性的LINQ查询需要知道在编译时存在多少个键和值,以便将数据投影到适当的类型中。

替代方案可能是将您的数据放入Dictionary<string,string>,这样您就可以为每个选项添加一个条目:

Dictionary<string,string> ProjectPerson(Person person)
{
    var results = Dictionary<string,string>();
    results.Add("Name", person.name);
    results.Add("Surname", person.surname);
    for (int i=0;i<person.aspect.Count;++i)
    {
         results.Add("aspectKey" + i.ToString(), person.aspect[i].key);             
         results.Add("aspectValue" + i.ToString(), person.aspect[i].value);
    }

    return results;
}

您的目标与此之间的主要区别在于您必须通过以下方式访问每个项目:

string name = projectedPerson["Name"];

而不是能够写:

string name = projectedPerson.Name;

如果您真的想使用最后一个选项,使用dynamic可以实现这一目标:

dynamic ProjectPerson(Person person)
{
    dynamic result = new ExpandoObject();
    var results = result as IDictionary<string, object>();
    results.Add("Name", person.name);
    results.Add("Surname", person.surname);
    for (int i=0;i<person.aspect.Count;++i)
    {
         results.Add("aspectKey" + i.ToString(), person.aspect[i].key);             
         results.Add("aspectValue" + i.ToString(), person.aspect[i].value);
    }

    return result;
}

这将允许你写:

dynamic projected = ProjectPerson(somePerson);

Console.WriteLine(projected.Name);
Console.WriteLine(projected.aspectKey3); // Assuming there are at least 4 aspects in the person