我有以下方法:
public string GetDepartmentTitle(string DepartmentAbbreviation) {
List<TaxonomyItem> Divisions = TaxonomyFromCMS.GetAllItems(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);
List<TaxonomyItem> Departments = new List<TaxonomyItem>();
Divisions.ForEach(delegate(TaxonomyItem Division) {
Departments.AddRange(Division.SubTaxonomyItems);
});
TaxonomyItem Result = (from d in Departments
where d.Name == DepartmentAbbreviation
select d).FirstOrDefault();
return Result == null ? "" : Result.Title;
}
它首先读取所有的Divisons(只有3个),但是这些Divides下面有许多Departments作为SubTaxonomyItems。目前,我逐步完成每个部门并提取出每个部门,并将它们放入名为Departments的列表中。然后我使用Linq搜索特定项目。
它的效果很好但是我想跳过/消耗获取子项的第一步。我尝试过以下似乎不起作用的行:
TaxonomyItem Result = (from d in Departments.SubTaxonomyItems
然后我通过某种类型的lambda与Departments.SubTaxonomyItems的foreach包含一个yeild语句。这可能是诀窍,但我无法让它发挥作用。看看yeild语句,如果我做一些扩展方法似乎有办法。但我想看看它是否可以内联完成,并且像下面的伪代码一样:
public string GetDepartmentTitle(string DepartmentAbbreviation) {
List<TaxonomyItem> Divisions = TaxonomyFromCMS.GetAllItems(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);
TaxonomyItem Result = (from d in Divisions.ForEach(delegate(TaxonomyItem Division) {
yeild return Divison.SubTaxonomyItems;
}) AS Dps
where Dps.Name == DepartmentAbbreviation
select Dps).FirstOrDefault();
return Result == null ? "" : Result.Title;
}
这可能是这种方式还是我没有看到的其他方式?它甚至可以在没有扩展方法的情况下完成吗?
答案 0 :(得分:12)
首先,只需在查询中添加“from”即可轻松解决问题:
var query = from division in divisions
from department in division.Departments
where department.Name == whatever
select department;
这正是你所做的;它从每个部门中选出部门序列,并将所有这些序列粘合在一起,形成一个长序列的部门。
这为您提供了“拼接一堆序列”场景的灵活语法。但更普遍的是,有时你遇到这种情况:
var bars = from foo in foos
some complicated query logic here
select foo.bar;
var abcs = from bar in bars
some other query logic here
select bar.abc;
并且您想要弄清楚如何将其转换为单个查询。你可以这样做:
var abcs = from bar in (
from foo in foos
some complicated query logic here
select foo.bar)
some other query logic here
select bar.abc;
丑陋,或者你可以这样做:
var abcs = from foo in foos
some complicated query logic here
select foo.bar into bar
some other query logic here
select bar.abc;
这完全相同,但阅读起来更愉快。此语法称为“查询延续”。
回答您的具体问题:在匿名方法或lambda中放置“yield return”是不合法的。这非常不幸,因为它非常有用。编译器为使匿名函数和迭代器块工作而执行的转换非常复杂,到目前为止,我们总是试图让它们完全协同工作。 (也就是说,你可以将一个lambda放在一个迭代器块中,但是你不能把一个迭代器块放在一个lambda中。)我希望,但不要保证,有一天我们能够修复这个代码并且允许迭代器阻塞lambda。 (请记住,Eric关于未来语言功能的思考仅适用于娱乐目的。)
答案 1 :(得分:2)
看起来你只是想要这样的东西。
public string GetDepartmentTitle(string DepartmentAbbreviation) {
var items = TaxonomyFromCMS.GetAllItems(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);
var result = items.SelectMany(item=>item.SubTaxonomyItems).FirstOrDefault(item=>item.Name == DepartmentAbbreviation);
var text = result !=null ? result.Title : String.Empty;
return text;
}
答案 2 :(得分:1)
收益率返回只能用于非常精选(双关语)位置,而Linq查询不是其中之一。幸运的是,你不需要它。
var q = from division in Divisions
from dps in division.SubTaxonomyItems
where dps.Name == DepartmentAbbreviation
select dps.Title;
return q.FirstOrDefault() ?? String.Empty;
答案 3 :(得分:0)
为什么不这样做:
var divisions = TaxonomyFromCMS.GetAllItems
(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);
var titles = from division in divisions
from deparment in division.SubTaxonomyItems
where deparment.Name == DepartmentAbbreviation
select deparment.Title;
return titles.FirstorDefault() ?? "";
答案 4 :(得分:0)
您正在寻找这个linq吗?
var Result = Divisions.SelectMany(d => d.SubTaxonomyItems).Where(subItem => subItem.Name == DepartmentAbbreviation).FirstOrDefault();