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

本文关键字:映射 一个对象 结果 查询 何使用 Select LINQ | 更新日期: 2023-09-27 17:58:44

我有一个对象层次结构,排列为大陆>国家>城市。我可以选择一个特定"国家"的所有城市,如下所示。我正在寻找一种方法来合并这两个查询,并在一个查询中获得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>();

cities中的"c"与cityList中的结构不同,因此第二个查询中的映射也不同。

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

只需在查询中使用点表示法:

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查询与您自己编写的查询类似,因此这一查询的可读性是它的优势。

您应该能够做到这一点:

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();

发布的选项的另一个替代方案:

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时不需要指定类型参数,该类型将被推断为City

尝试以下操作:

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