如何在 Linq 查询中使用 Yield

发布于 2024-11-02 14:10:17 字数 1774 浏览 1 评论 0原文

我有以下方法:

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

它首先读取所有部门(只有 3 个),但这些部门下面有许多部门作为 SubTaxonomyItems。目前,我遍历每个部门并提取每个部门并将它们放入一个名为“部门”的列表中。然后我使用 Linq 来搜索特定项目。

它效果很好,但我想跳过/消耗获取子项目的第一步。我尝试了以下行,但似乎不起作用:

TaxonomyItem Result = (from d in Departments.SubTaxonomyItems

然后,我可能通过某种带有包含 yield 语句的 Departments.SubTaxonomyItems 的 foreach 的 lambda 。这可能是窍门,但我无法让它发挥作用。看看 yield 语句,如果我做一些扩展方法,似乎可以有办法。但我想看看它是否可以内联完成,就像下面的伪代码一样:

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

这可能是这种方式还是我没有看到的其他方式?甚至可以在没有扩展方法的情况下完成吗?

I have the following method:

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

It first reads all of the Divisons (which there are only 3) but those divisions have many Departments below them as SubTaxonomyItems. Currently I step through each of the Divisions and extract out each of the Departments and put them in a List called Departments. Then I use Linq to search for the specific item.

It works great but I would love to skip/consume that first step of getting the sub items. I have tried the following line that doesn't seem to work:

TaxonomyItem Result = (from d in Departments.SubTaxonomyItems

I then through perhaps some sort of lambda with a foreach of the Departments.SubTaxonomyItems that contains a yeild statement. That may be the trick, but I couldn't get it to work. Looking into the yeild statement it seems there can be a way if I make some extension method. But I am wanting to see if it can be done inline and like the following pseudo code:

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

Is this possible this way or some other way I am not seeing? Can it even be done without an extension method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小ぇ时光︴ 2024-11-09 14:10:17

首先,您只需在查询中添加另一个“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 对未来语言功能的思考仅供娱乐。)

First off, you can solve your problem easily by just adding another "from" to the query:

var query = from division in divisions
            from department in division.Departments
            where department.Name == whatever
            select department;

This does exactly what you were doing; it selects out the sequence of departments from each division, and glues all those sequences together to make one long sequence of departments.

This gives you a slick syntax for the "stitch together a bunch of sequences" scenario. More generally though, sometimes you run into this sort of situation:

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;

and you want to figure out how to make this into a single query. You can do that like this:

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;

which is ugly, or you can do this:

var abcs = from foo in foos
           some complicated query logic here
           select foo.bar into bar
           some other query logic here
           select bar.abc;

That does exactly the same thing but it is more pleasant to read. This syntax is called a "query continuation".

To answer your specific question: it is not legal to put a "yield return" in an anonymous method or lambda. This is quite unfortunate because it would be really useful. The transformations that the compiler performs to make anonymous functions and iterator blocks work are quite complex and thus far we have always punted on getting them to work together fully. (That is, you can put a lambda in an iterator block, but you can't put an iterator block in a lambda.) I hope, but do not promise, that some day we'll be able to fix this code up and allow iterator block lambdas. (Remember, Eric's musings about future language features are For Entertainment Purposes Only.)

触ぅ动初心 2024-11-09 14:10:17

看起来你只是想要这样的东西。

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

It looks like you just want something like this.

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;
}
梦中的蝴蝶 2024-11-09 14:10:17

Yield return 只能在非常选定(双关语!)的位置使用,而 Linq 查询不是其中之一。幸运的是你在这里不需要它。

var q = from division in Divisions
        from dps in division.SubTaxonomyItems
        where dps.Name == DepartmentAbbreviation
        select dps.Title;

return q.FirstOrDefault() ?? String.Empty;

Yield return can only be used in very select (pun!) locations, and a Linq query isn't one of them. Luckily you don't need it here.

var q = from division in Divisions
        from dps in division.SubTaxonomyItems
        where dps.Name == DepartmentAbbreviation
        select dps.Title;

return q.FirstOrDefault() ?? String.Empty;
葬花如无物 2024-11-09 14:10:17

为什么不直接做:

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

Why not just do:

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() ?? "";
围归者 2024-11-09 14:10:17

这是您要找的 linq 吗?

var Result = Divisions.SelectMany(d => d.SubTaxonomyItems).Where(subItem => subItem.Name == DepartmentAbbreviation).FirstOrDefault();

Is this linq you are looking for?

var Result = Divisions.SelectMany(d => d.SubTaxonomyItems).Where(subItem => subItem.Name == DepartmentAbbreviation).FirstOrDefault();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文