Использование группы в запросе LINQ

#linq #dynamics-crm #dynamics-crm-2011

#linq #dynamics-crm #dynamics-crm-2011

Вопрос:

Я использую LINQ для поставщика CRM.

Я запрашиваю информацию, затем я использую LINQ для запроса запроса LINQ to CRM, чтобы я мог использовать GroupBy, поскольку поставщик LINQ to CRM его не поддерживает. Это то, что у меня есть до сих пор.

 var linqQuery = (from r in orgServiceContext.CreateQuery("opportunity")
    join c in orgServiceContext.CreateQuery("contact") on 
        ((EntityReference)r["new_contact"]).Id equals c["contactid"] into opp
    from o in opp.DefaultIfEmpty()
    select new
    {
        OpportunityId = !r.Contains("opportunityid") 
            ? string.Empty : r["opportunityid"],
        CustomerId = !r.Contains("customerid") 
            ? string.Empty : ((EntityReference)r["customerid"]).Name,
        OwnerId = !r.Contains("ownerid") 
            ? string.Empty : ((EntityReference)r["ownerid"]).Id.ToString(),
        OwnerName = !r.Contains("ownerid") 
            ? string.Empty : ((EntityReference)r["ownerid"]).Name.ToString(),
        Priority = !r.Contains("opportunityratingcode") 
            ? string.Empty : r.FormattedValues["opportunityratingcode"],
        ContactName = !r.Contains("new_contact") 
            ? string.Empty : ((EntityReference)r["new_contact"]).Name,
        // ...
        // other properties  
    });

var linqQuery2 = (from f in linqQuery.ToList()
                  group f by f.OwnerId into myGroup
                  select new
                  {
                      OrderCount = myGroup.Count()
                  });
  

Но я также хочу иметь возможность запрашивать другие переменные, которые находятся в linqQuery from linqQuery2 .

Поэтому я хотел бы что-то вроде:

 var linqQuery2 = (from f in linqQuery.ToList()
                  group f by f.OwnerId into myGroup
                  select new
                  {
                      OwnerName = myGroup.OwnerName,
                      OrderCount = myGroup.Count()
                  });
  

Возможно ли это сделать?

Ответ №1:

Предполагая, что имена владельцев будут одинаковыми для всех элементов в группе, вы можете сделать что-то вроде:

 var linqQuery2 = (from f in linqQuery.ToList()
    group f by f.OwnerId into myGroup
    select new
    {
        OwnerName = myGroup.First().OwnerName,
        OrderCount = myGroup.Count()
    });
  

Редактировать:

Если вы хотите использовать первый элемент несколько раз, я бы посоветовал вам использовать оператор ‘let’:

 var linqQuery2 = (from f in linqQuery.ToList()
                    group f by f.OwnerId into myGroup
                    let first = myGroup.First()
                    select new
                    {
                        OwnerName = first.OwnerName,
                        OrderCount = myGroup.Count()
                    });
  

Комментарии:

1. Спасибо, что, похоже, сработало. Если я хочу получить больше переменных из первого запроса, скажем, «Примечания», могу ли я продолжать использовать First ()?

2. Вы, конечно, можете, хотя каждый раз, когда вы вызываете First() или Count(), вы вызываете другую оценку отложенного запроса linq. Решение этой проблемы см. в разделе Редактирование.

3. Есть ли способ сделать так, чтобы он искал все из них в группе по определенному значению, а не только первое. Так, например. Он подсчитывает все переменные LeadShare со значением 100000000. Итак, если у меня есть 10 владельцев с одинаковым идентификатором, и 5 из них имеют значение LeadShare 100000000, то это дает значение 5. Прямо сейчас кажется, что он просто ищет первый, и если он не совпадает, он игнорирует остальные. Спасибо!

4. Вероятно, лучше всего опубликовать новый вопрос для этого. На самом деле я еще не потратил кучу времени на LINQ и CRM2011.

Ответ №2:

Попробуйте

         var linqQuery2 = (from f in linqQuery.ToList()
                          group f by f.OwnerName
                          into myGroup
                          select new
                                     {
                                         OwnerName = myGroup.Key,
                                         OwnerCount = myGroup.Count()
                                     });
  

Поочередно:

         var linqQuery2 = linqQuery.ToList()
            .GroupBy(f => f.OwnerName)
            .Select(myGroup => new
                                {
                                    OwnerName = myGroup.Key,
                                    OwnerCount = myGroup.Count()
                                });
  

Комментарии:

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

2. Спасибо. Однако это не позволяет мне выбирать другие переменные из linqQuery.