#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, как только у меня появится свободное время. Спасибо за ваши уроки. Это действительно полезно.