LINQ加入子选择

时间:2014-02-28 17:58:39

标签: c# linq

我有两个内存列表,我想加入一个子选择。对于直接LINQ Join构造,它似乎不可行。有什么建议吗?

Authors = {
    { Name = "Tom", Ref = { 1, 2, 3 } },
    { Name = "Dick", Ref = { 3, 4, 5 } },
    { Name = "Harry", Ref = { 1, 5 } }
}

Refs = {
    { ID = 1, Location = "Home" },
    { ID = 2, Location = "Work" },
    { ID = 3, Location = "School" },
    { ID = 4, Location = "Camping" },
    { ID = 5, Location = "Travel" }
}

Result = {
    { Name = "Tom", Locations = { "Home", "Work", "School" } },
    { Name = "Dick", Locations = { "School", "Camping", "Travel" } },
    { Name = "Harry", Locations = { "Home", "Travel" } }
}

4 个答案:

答案 0 :(得分:3)

试试这个:

Authors.Select(
    i=>new {Name = i.Name, 
            Locations = Refs.Where(
                          j=>i.Ref.Contains(j.ID)).Select(j=>j.Location)});

答案 1 :(得分:2)

您可以通过以下方式避免 join on sub-select

Authors.Select(author => new {
                                Name = author.Name, 
                                Locations = author.Ref.Select(id => Refs.Single(x => x.ID == id).Location)
                            }
              );

修改

为了优化sub-select的效果,我宁愿制作Refs字典,然后直接在sub-select中使用它,如下所示:

var dictRefs = Refs.ToDictionary(key => key.ID, value => value.Location);
var Results = Authors.Select(author => new {
                                Name = author.Name, 
                                Locations = author.Ref.Select(id => dictRefs[id])
                                           }
                            );

答案 2 :(得分:1)

首先,让我们创建几个类:

public class Author {
    public string Name { get; set; }
    public IList<int> Ref { get; set; } 
}

public class Ref {
    public int ID { get; set; }
    public string Location { get; set; }
}

public class Result {
    public string Name { get; set; }
    public IList<string> Locations { get; set; } 

    public override string ToString() {
        return string.Format("Name: {0}. Locations: {1}", Name, string.Join(", ", Locations));
    }
}

以下代码可以解决问题:

var authors = new List<Author>
    {
        new Author {Name = "Tom", Ref = new List<int> {1, 2, 3}},
        new Author {Name = "Dick", Ref = new List<int> {3, 4, 5}},
        new Author {Name = "Harry", Ref = new List<int> {1, 5}},
    };

var refs = new List<Ref>
    {
        new Ref {ID = 1, Location = "Home"},
        new Ref {ID = 2, Location = "Work"},
        new Ref {ID = 3, Location = "School"},
        new Ref {ID = 4, Location = "Camping"},
        new Ref {ID = 5, Location = "Travel"}
    };

var result = authors.Select(x => new Result
    {
        Name = x.Name,
        Locations = x.Ref.Select(y => refs.FirstOrDefault(z => z.ID == y).Location).ToList()
    }).ToList();


result.ForEach(x => Console.WriteLine(x));

上面的代码将打印出来:

  

姓名:汤姆。地点:家庭,工作,学校   姓名:迪克。地点:学校,露营,旅游   姓名:哈利。地点:家,旅行

假设所有ID都存在于refs

答案 3 :(得分:0)

from a in Authors
select new {Name = a.Name, 
           Locations = Refs.Where(r=>a.Ref.Contains(r.ID)).Select(r=>r.Location)}