LINQ查询 - 如何使用Select将结果集映射到另一个对象

时间:2011-06-07 06:07:56

标签: c# linq

我有一个对象层次结构,排列为大陆>国家>城市。能够选择特定“国家/地区”中的所有城市,如下所示。我正在寻找的是一种合并这两个查询的方法,并在单个查询中到达cityList。

var cities = network.Continents
    .SelectMany(continent => continent.Countries)
    .Where(ctry => ctry.Id == "country")
    .SelectMany(ctry => ctry.Cities);

List<City> cityList = (from c in cities
                        select new City { Id = c.Id, Name = c.Name }).ToList<City>();

“城市中的c”与cityList中的结构不同,因此在第二个查询中具有不同的结构。

4 个答案:

答案 0 :(得分:11)

在查询中使用点表示法:

var cities = network.Continents
    .SelectMany(continent => continent.Countries)
    .Where(ctry => ctry.Id == "country")
    .SelectMany(ctry => ctry.Cities)
    .Select(cty=> new City{Id = cty.Id, Name = cty.Name }).ToList<City>();

我认为它是可读的,并且它没有额外的开销,生成的sql查询在大多数情况下都是类似的,你可以这样做,所以只是可读性很重要。

答案 1 :(得分:5)

你应该能做到这一点:

var cityList = network.Continents
    .SelectMany(continent => continent.Countries)
    .Where(ctry => ctry.Id == "country")
    .SelectMany(ctry =>
        ctry.Cities.Select(c => new City { Id = c.Id, Name = c.Name })
    ).ToList();

可替换地:

var cityList =
    (from continent in network.Continents
     from country in continent.Countries
     where country.Id == "country"
     from city in country.Cities
     select new City { Id = city.Id, Name = city.Name })
    .ToList();

答案 2 :(得分:5)

发布选项的另一种选择:

var cityList = network.Continents
                      .SelectMany(continent => continent.Countries)
                      .Where(ctry => ctry.Id == "country")
                      .SelectMany(ctry =>  ctry.Cities,
                                  c => new City { Id = c.Id, Name = c.Name })
                      .ToList();

SelectMany的重载(在第二次调用中)是C#编译器在查询表达式中使用的重载。请注意,如果要将其编写为查询表达式,则可以轻松地执行此操作:

var cityList = (from continent in network.Continents
                from country in continent.Countries
                where country.Id == "country"
                from city in country.Cities
                select new City { Id = city.Id, Name = city.Name }).ToList(); 

在LINQ to Objects中,在这种特殊情况下,查询表达式稍微效率低于点符号形式,因为大陆和国家范围变量将向下传播到select子句......但我希望任何数据库LINQ提供程序生成的SQL都是相同的,即使在LINQ to Objects中,差异也可能微不足道。

请注意,调用ToList时无需指定type参数 - 该类型将被推断为City

答案 3 :(得分:4)

尝试以下方法:

var cities = 
    from continent in network.Continents
    from country in continent.Countries
    from city in country.Cities
    where country.Id = "country"
    select new City { Id = c.Id, Name = c.Name };