Как преобразовать оператор Linq Group By и Foreach в один запрос Linq - PullRequest
0 голосов
/ 01 марта 2019

У меня возникли проблемы при попытке преобразовать приведенный ниже запрос LINQ в один запрос:

// produces 8 results
            var qryResults =
                (from r in dbContext.Routes
                 join br in dbContext.BrokerRoutes on r.RouteId equals br.RouteId
                 join pr in dbContext.RoutePathFilters.Include(x => x.PathFilter) on r.RouteId equals pr.RouteId into paths
                 where br.Broker.ApiKey == apiKey
                 select new RouteTemplate
                    {
                        RouteId = r.RouteId,
                        Version = r.Version.Version,
                        Url = r.Url,
                        IsActive = r.IsActive,
                        Paths = paths.Select(x => x.PathFilter.FilterName).ToList()
                 })
                .AsNoTracking()
                .ToImmutableList();
// takes 8 results and turns that into 2 overall objects.
            var results = new List<RouteTemplate>();
            foreach (var r in qryResults)
            {
                if (results.All(x => x.RouteId != r.RouteId))
                {
                    r.Paths = qryResults
                        .Where(x => x.RouteId == r.RouteId)
                        .Select(x => x.Paths.First()).ToList();
                    results.Add(r);
                }
            }

r дублируется каждым значением, содержащимся в свойстве paths.

Я знаю, что foreach можно объединить в приведенный выше запрос linq, но я пробовал уже несколько часов.Так что мне интересно знать, возможно ли это или нет и как это можно сделать?

1 Ответ

0 голосов
/ 01 марта 2019

Без реальной базы данных я не уверен, сработает ли это, но вот моя попытка:

var qryResults =
    (from r in dbContext.Routes
     join br in dbContext.BrokerRoutes on r.RouteId equals br.RouteId
     where br.Broker.ApiKey == apiKey
     join pr in dbContext.RoutePathFilters.Include(x => x.PathFilter) on r.RouteId equals pr.RouteId into paths
     group new { r, paths } by r.RouteId into rprg
     let r = rprg.First().r
     select new RouteTemplate {
         RouteId = rprg.Key,
         Version = r.Version.Version,
         Url = r.Url,
         IsActive = r.IsActive,
         Paths = rprg.Select(rpr => rpr.paths.First().PathFilter.FilterName).ToList()
     })
    .AsNoTracking()
    .ToImmutableList();
...