Почему мой запрос LINQ to Objects не возвращает никаких результатов? - PullRequest
2 голосов
/ 10 июля 2009

У меня есть следующий запрос, который я использую (который в основном пришел от помощи, которую я получил здесь ):

    public IEnumerable<Entities.AuditAgency> GetAuditRuleAgencyRecords(IEnumerable<Entities.AuditRuleEnterprise> rules)
    {
        using (LinqModelDataContext db = new LinqModelDataContext())
        {
            // Left-Outer Joins on Agency and its various other tables.
            var auditAgencyRecords = (from ag in db.Agencies
                                      join ara in db.AuditRuleAccounts on ag.Agency_Id equals ara.AgencyID into aran
                                      from ara in aran.DefaultIfEmpty()
                                      join arr in db.AuditRuleResults on ara.AuditRuleAccountID equals arr.AuditRuleAccountID into arrn
                                      from arr in arrn.DefaultIfEmpty()
                                      join are in db.AuditRuleEnterprises on arr.AuditRuleEnterpriseID equals are.AuditRuleEnterpriseID into aren
                                      from are in aren.DefaultIfEmpty()
                                      select new
                                      {

                                          AgencyID = ag.Agency_Id,
                                          AgencyName = ag.Agency_Name,
                                          AuditRuleEnterpriseID = arr.AuditRuleEnterpriseID,
                                          AuditRuleEnterpriseName = are.OverrideDisplayName,
                                          CorrectedDate = arr.CorrectedDate,
                                          NbrDaysToCorrect = arr.NbrDaysToCorrect,

                                      });

            IEnumerable<AuditAgency> AuditAgencies = auditAgencyRecords
                .GroupBy(a => a.AgencyID)
                .Select(ag => new AuditAgency()
                {
                    AgencyID = ag.Key,
                    AgencyName = ag.First().AgencyName,
                    Rules = ag
                    .GroupBy(agr => agr.AuditRuleEnterpriseID) 
       //  ---->          Do a left outer join on parameter "rules" object and the returned group above
       //   ---->          on both of their ID's
                    .Select(agrg => new AuditAgencyRule() // Now I would like to only be creating "rules" for the rules with IDs that match the rules passed into this method
                    {
                        AuditRuleID = agrg.Key,
                        AuditRuleName = agrg.First().AuditRuleEnterpriseName,
                        Days = (Int32)agrg.Average(agrgr => agrgr.NbrDaysToCorrect)
                    })
                }).ToList();

            return AuditAgencies;

        }

Это возвращает мне список объектов AuditAgency, и каждый AuditAgency содержит список AuditAgencyRules.

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

То, что я хотел бы сделать, - это мой второй запрос, где он создает список правил для каждого агентства, я хочу выполнить левое внешнее объединение с моим локальным объектом «правила». У каждого объекта правила, который я передаю, есть rule.ID. Я хочу, чтобы каждое агентство содержало только переданные правила, и если для них нет данных, просто оставьте их содержимое пустым.

Прямо сейчас мой запрос содержит все правила, возвращенные из базы данных, и их данные. Однако мне нужно, чтобы он содержал только правила, переданные в метод, независимо от того, соответствует ли он правилам, возвращаемым из базы данных. Другими словами, мне нужно выполнить левое внешнее соединение для моего локального объекта «rules» с правилами, которые у меня есть там сейчас.

Вы можете видеть, где я добавил комментарии к приведенному выше коду, чтобы объяснить, где и что я пытаюсь сделать.

Таким образом, если «rules» содержит только 3 правила с набором их идентификаторов, то этот запрос будет возвращать только эти 3 правила для каждого агентства, независимо от того, есть ли данные для этих правил (его данные будут нулевыми). Вместо того, чтобы возвращать все правила для каждого агентства, то, что оно делает сейчас.

Как мне написать это левое внешнее соединение для "локального" объекта в моем запросе LINQ to SQL?


Вот моя попытка выполнить левое внешнее соединение для моего объекта «rules» и правил в моих AuditAgencies после второго запроса, приведенного выше:

foreach (var agency in AuditAgencies)
{
    agency.Rules = from rule in rules
                   join lr in agency.Rules on rule.EnterpriseID equals lr.AuditRuleID into g
                   from lr in g.DefaultIfEmpty()
                   select new AuditAgencyRule
                   {
                       AuditRuleID = rule.EnterpriseID,
                       AuditRuleName = rule.Name,
                       Days = lr.Days,
                       Flagged = lr.Flagged,
                       PercentFlagged = lr.PercentFlagged
                   };
}

Без кубиков. Теперь вместо всех правил я получаю никаких правил. Когда все, что я хочу, это просто получить правила, которые я передаю в этот метод.

Может ли кто-нибудь указать мне правильное направление?

Ответы [ 3 ]

1 голос
/ 14 июля 2009

Я могу предложить вам немного мета-помощи. Вам нужно взять LINQPad и начать использовать .Dump (), чтобы увидеть, в чем вы идете (вы также можете посмотреть и на прямые переводы SQL).

0 голосов
/ 14 июля 2009

Это может быть связано с отложенным запросом, который еще не вернулся, особенно если учесть, что вы используете IEnumeratable <> ... проверить Блог Чарли Калверта на эту тему, чтобы быстро проверить, можете ли вы попробовать подсунуть что-то вроде присваивания .ToArray (), которое приведет к немедленному выполнению запроса.

0 голосов
/ 10 июля 2009

По сути, вы делаете левое внешнее соединение с локальными объектами так же, как и с любым другим источником Linq. Проблема возникает, когда поставщик может не понимать, что вы делаете.

Итак, вы пробовали очевидный способ проверить, работает ли он? Если это не сработает, то вам может быть разумно просто вернуть результаты и отфильтровать нежелательные правила в третьем операторе Linq.

...