Как использовать доходность внутри запроса Linq - PullRequest
2 голосов
/ 21 апреля 2011

У меня есть следующий метод:

    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

Затем я, возможно, через какую-то лямбду с предисловием из Departments.SubTaxonomyItems, содержащего выражение 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;
    }

Возможно ли это так или иначе, я не вижу? Можно ли это сделать даже без метода расширения?

Ответы [ 5 ]

12 голосов
/ 21 апреля 2011

Во-первых, вы можете легко решить свою проблему, просто добавив еще одно «от» к запросу:

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;

Это точно так же, но читать приятнее. Этот синтаксис называется «продолжение запроса».

Чтобы ответить на ваш конкретный вопрос: не разрешено помещать «доходность» в анонимный метод или лямбду. Это довольно прискорбно, потому что это было бы действительно полезно. Преобразования, которые выполняет компилятор, чтобы заставить анонимные функции и блоки итераторов работать, довольно сложны, и до сих пор мы всегда старались заставить их работать вместе полностью. (То есть вы можете поместить лямбду в блок итератора, но вы не можете поместить блок итератора в лямбду.) Я надеюсь, но не обещаю, что когда-нибудь мы сможем исправить этот код и разрешить итератору блокировать лямбды. (Помните, размышления Эрика о будущих функциях языка предназначены только для развлекательных целей.)

2 голосов
/ 21 апреля 2011

Похоже, вы просто хотите что-то подобное.

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;
}
1 голос
/ 21 апреля 2011

Возврат доходности может использоваться только в очень избранных (каламбурных) местах, и запрос Linq не является одним из них.К счастью, вам здесь не нужно.

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

return q.FirstOrDefault() ?? String.Empty;
0 голосов
/ 21 апреля 2011

Этот linq вы ищете?

var Result = Divisions.SelectMany(d => d.SubTaxonomyItems).Where(subItem => subItem.Name == DepartmentAbbreviation).FirstOrDefault();
0 голосов
/ 21 апреля 2011

Почему бы просто не сделать:

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() ?? "";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...