Как получить свойства в LINQ после предложения group by?

#c# #linq #asp.net-mvc-4

#c# #linq #asp.net-mvc-4

Вопрос:

Я пишу один запрос linq с предложением group by. Я не могу получить свойства из одной таблицы. Моя загружаемая структура выглядит следующим образом

     upld_docid  upld_clientid  upld_employeeid
    1002        1008           1111

    My UploadLogTable

        upld_docid      Label          value          Commited  UpdatedBy
        1002            Docnumber      123            False     Niranjan
        1002            ExpiryDate     01/01/2017     False     Niranjan
        1002            Docnumber      456            True      Azeeza
        1002            ExpiryDate     01/01/2019     True      Azeeza

    I am expecting output as

   upld_clientid  upld_employeeid  Lable        oldvalue    newValue   UpdatedBy
    1008           1111             Docnumber    123         456        Azeeza
    1008           1111             ExpiryDate   01/01/2017  01/01/2019 Azeeza
  

Я написал запрос Linq, и я получаю все поля, ожидающие поля updatedby, потому что я группирую все, но поле Updatedby содержит разные значения.

 var logDetails = (from c in db.ts_upldlog_content
                  join tbl in db.ts_upld_doc on c.upld_docid equals tbl.upld_docid
                  join doc in db.tm_doc_type on tbl.upld_doctypeid equals doc.doc_typeid
                  where (c.commited == false || c.commited == true)
                     amp;amp; (tbl.upld_clientid == clientId || tbl.upld_employeeid == employeeID || tbl.upld_empcitizenid == citizenId)
                  group c by new { c.upld_docid, c.upld_contentlabel, tbl.upld_clientname,tbl.upld_clientid,tbl.upld_employeeid} into grouping
                  select new logDetails
                  {
                      CId=grouping.Key.upld_clientid.Value,
                      employeeID=grouping.Key.upld_employeeid,
                      contentLabel = grouping.Key.upld_contentlabel,
                      upld_id = grouping.Key.upld_docid,
                      UpdatedBy=?  //Here I am not sure how to get updatedby
                      oldValue = grouping.FirstOrDefault(x => x.commited == false).upld_contentvalue,
                      newValue = grouping.FirstOrDefault(x => x.commited == true).upld_contentvalue,
                  });
return logDetails.ToList();
  

Могу ли я узнать, как получить свойство UpdatedBy в приведенном выше запросе? Любая помощь будет оценена. Спасибо.

Ответ №1:

Используйте let ключевое слово перед select и после group by , чтобы создать переменную, содержащую запись, относящуюся к new data и для old data :

 var logDetails = (from c in db.ts_upldlog_content
                  join tbl in db.ts_upld_doc on c.upld_docid equals tbl.upld_doci
                  join doc in db.tm_doc_type on tbl.upld_doctypeid equals doc.doc_typeid
                  where (c.commited == false || c.commited == true) amp;amp;
                        (tbl.upld_clientid == clientId || tbl.upld_employeeid == employeeID || tbl.upld_empcitizenid == citizenId)
                  group c by new { c.upld_docid, c.upld_contentlabel, tbl.upld_clientname,tbl.upld_clientid,tbl.upld_employeeid } into grouping

                  let OldValue = grouping.FirstOrDefault(x => x.commited == false)
                  let NewValue = grouping.FirstOrDefault(x => x.commited == true)

                      select new logDetails
                      {
                          CId=grouping.Key.upld_clientid.Value,
                          employeeID=grouping.Key.upld_employeeid,
                          contentLabel = grouping.Key.upld_contentlabel,
                          upld_id = grouping.Key.upld_docid,
                          UpdatedBy = NewValue.updated_by
                          oldValue = OldValue.upld_contentvalue,
                          newValue = NewValue.upld_contentvalue,
                      }).ToList();
  

Другой способ, если ваши данные могут содержать, для ваших групповых столбцов только 1 запись commited , равная to true и 1 to false , и у вас правильно определены все индексы, — выбрать один «тип» записей (те, с commited == true ), а затем объединить с другим «типом».

 var upld_content_view = from c in db.ts_upldlog_content
                        join tbl in db.ts_upld_doc on c.upld_docid equals tbl.upld_docid
                        join doc in db.tm_doc_type on tbl.upld_doctypeid equals doc.doc_typeid
                        select new { c, tbl, doc };

var result = (from u1 in upld_content_view
              where u1.commited == true amp;amp;
                    (tbl.upld_clientid == clientId || tbl.upld_employeeid == employeeID || tbl.upld_empcitizenid == citizenId)
              join u2 in upld_content_view.Where(item => item.commited == false)
              on new { u1.upld_docid, u1.upld_contentlabel }    equals  new { u2.upld_docid, u2.upld_contentlabel }  
              select new logDetails
              {
                 CId = u1.upld_clientid.Value,
                 employeeID = u1.upld_employeeid,
                 contentLabel = u1..upld_contentlabel,
                 upld_id = u1.upld_docid,
                 UpdatedBy = u1.updated_by // u1 represents the data of the NewValue
                 oldValue = u2.upld_contentvalue,
                 newValue = u1.upld_contentvalue,
              }).ToList();
  

Таким образом, вы точно знаете, что запись u1 представляет общие данные, а данные, которые вы хотите, которые связаны с NewValue while u2 , предназначены для данных, связанных с OldValue .

Если предположение о втором способе верно, то оба способа должны быть проверены на производительность и проверить, каков сгенерированный sql план выполнения базы данных.

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

1. Сработало как шарм. Я хочу изучить LINQ, как только у меня появится свободное время. Спасибо за ваши уроки. Это действительно полезно.