我有一个对象层次结构,排列为大陆>国家>城市。能够选择特定“国家/地区”中的所有城市,如下所示。我正在寻找的是一种合并这两个查询的方法,并在单个查询中到达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中的结构不同,因此在第二个查询中具有不同的结构。
答案 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 };