Linq: делает предложение Where () для вложенной модели - PullRequest
4 голосов
/ 01 ноября 2010

Это может показаться сложным, но я на самом деле просто пытаюсь выбрать все записи и их детей из A, где у их детей существуют определенные условия. В поисках синтаксиса, который я могу добавить к переменной A, которая позволяет мне фильтровать несколько условий (например, шаблон спецификации?)

Если у вас есть вложенное представление, подобное этому:

var a = from Arow in Atable
        where ???
        select new AViewModel {                    // (image Products)
            id = Arow.id,
            name = Arow.Name,
            Brows = (from Brow in Arow.Brows
                     select new BViewModel {       // (sold in different regions)
                         id = Brow.id,
                         name = Brow.Name,
                         Crows = (from Crow in Brow.Crows
                                  select new CViewModel { // (and in many stores)
                                      id = Crow.id,
                                      name = Crow.Name
                                  }
                     }
        };

И текст, представляющий запросы с веб-страницы, подобной этой (шаблон спецификации?) Мы использовали селекторы JQuery для операторов (например, ^ = означает «начинается с»)

filter[] = { "Brow.Name = Joe", "Crow.Name = Kim" }

Как вы можете отфильтровать выражение A по этим критериям? Другими словами, можете ли вы иметь выражение where, например a.Where (), которое может фильтровать вложенные свойства?

Моя неудачная попытка:

var b = from row in a
        where a.Brow.Where(b => b.name == "Joe") &&
              a.Brow.Crow.Where(c => c.name == "Kim")
        select row;

Что мне действительно нужно, так это:

Select * 
from A join B on A.key = B.key join C on B.key = C.key -- propagated keys
where exists (select null from B where A.key = B.key and B.Name = "Joe") and
      exists (select null from C where A.key = C.key and C.Name = "Kim")

Особенно, если я смогу сделать это:

var result = a.Where(first).Where(second);

Ответы [ 2 ]

7 голосов
/ 01 ноября 2010

Ваша "неудачная попытка" не так уж и далека. Просто замените Any() на Where():

var b = from row in a
        where a.Brow.Any(b => b.name == "Joe") &&
              a.Brow.Crow.Any(c => c.name == "Kim")
        select row;

Отредактировано, чтобы добавить:

Возможно, вы захотите провести сравнение без учета регистра, например, .Any(b => b.name.Equals("Joe", StringComparison.CurrentCultureIgnoreCase)).

2 голосов
/ 01 ноября 2010

Или ради интереса, вы можете сделать лямбда-эквивилант:

var b = a.where(x => x.Brow.Any(b => b.name == "Joe") 
                     && x.Brow.Crow.Any( c => c.name == "Kim")
         .Select(y => y.row);
...