Проблемы с оператором.NET Linq
Синтаксис Linq и Query - один из моих самых слабых навыков. У меня проблемы с получением желаемого результата.
У меня есть две таблицы / коллекции. Один заполнен DocumentTypes, другой с Уведомлениями. Это те поля, которые они содержат, но я пропустил те, которые этого не делают.
DocumentTypes
- Я БЫ
- название
- SupplierID
Уведомления
- Я БЫ
- DocumentTypeID
- Идентификатор пользователя
- Код товара
- Last_Sequence
У меня есть три параметра; идентификатор пользователя, идентификатор поставщика и идентификатор продукта.
Мне нужен идентификатор поставщика, чтобы получить список всех типов документов, связанных с этим поставщиком. Затем мне нужны userID и ProductID, чтобы получить список уведомлений, связанных с ними.
Затем мне нужно присоединиться к этим двум спискам, каждое уведомление будет иметь documentTypeID, с которым оно связано. Когда есть уведомление для определенного типа документа, оно должно включать в себя поля Last_Sequence и создать новое поле bool, для которого установлено значение true.
Когда уведомления нет, Last_sequence можно оставить пустым, а bool создается и устанавливается в false.
Таким образом, результатом будет список объектов, которые имеют эти типы.
- DocumentTypeID
- DocumentTypeName
- BoolField (правда, есть уведомление, привязанное к этому)
- NotificationID (только если есть)
- Last_sequence (только если есть)
Что у меня так далеко.
В предыдущей версии требовалось только добавить поле bool вместе с информацией documentType. Для этого у меня было это утверждение, но я не могу добавить к этому то, что мне нужно:
List<DocumentTypeNotification> docTypes = repository.Get<Domain.DocumentType>().Where(d => d.SuppID == SuppId).Select(d => new DocumentTypeNotification
{
DocTypeID = d.Id,
DocTypeName = d.Name,
Subscribed = notifications.Any(n => n == d.Id)
}).ToList();
Что я пробовал для нового, так это, но он возвращает данные только тогда, когда есть связанное уведомление. Когда его нет, он не возвращает эти данные documentType.
var temptest = from notif in repository.Get<Domain.Notification>()
join doctype in repository.Get<Domain.DocumentType>() on notif.DocTypeId equals doctype.Id
select new DocumentTypeNotification { DocTypeID = doctype.Id, DocTypeName = doctype.Name, Subscribed = true, NotifID = notif.Id, last_sequence = notif.Last_Sequence};
РЕДАКТИРОВАТЬ: вот пример того, что я пытался, но не работает. Проблема здесь в том, что n не существует, когда я пытаюсь сделать n.last_sequence.
List<DocumentTypeNotification> docTypes = repository.Get<Domain.DocumentType>().Where(d => d.SuppID == SuppId).Select(d => new DocumentTypeNotification
{
DocTypeID = d.Id,
DocTypeName = d.Name,
Subscribed = notifications.Any(n => n == d.Id),
last_sequence = test.Where(n => n.DocTypeId == d.Id).Select(n.Last_Sequence).FirstOrDefault()
//from n in test
//where n.DocTypeId == d.Id
//select n.Last_Sequence
}).ToList();
Мне было интересно, как я должен решить это. Нужно ли мне сначала создать коллекцию всех правильных типов документов, а затем объединить их с новой созданной мной коллекцией, или есть лучший способ решить эту проблему?
2 ответа
Как насчет левого соединения
from d in repository.Get<Domain.DocumentType>()
join n in repository.Get<Domain.Notification>()
on d.Id equals n.DocTypeId
into temp
from notific in temp.DefaultIfEmpty()
where d.SuppID == SuppId
select new
{
d.Name,
last_sequence = notific != null ? notific.Last_Sequence : null,
Subscribed = notific != null
}
Конкретных примеров кода не существует, поэтому сначала я определю некоторые переменные. Давайте предположим, что у нас есть список типов документов с именем documentTypes
и список уведомлений с именем notifications
, Если я правильно понимаю вашу проблему, то следующий запрос linq сделает то, что вы хотите
documentTypes.Where(d => d.SupplierID == SuppId)
.GroupJoin(notifications,
d => d.ID,
n => n.DocumentTypeID,
(document, notification) => new {document, notification}
)
.Select(join =>
{
var anyNotification = join.notification.FirstOrDefault();
return new
{
DocTypeID = join.document.ID,
DocTypeName = join.document.Name,
Subscribed = join.notification.Any(),
NotificationID = anyNotification != null ? anyNotification.ID : null,
Last_sequence = anyNotification != null ? anyNotification.Last_Sequence: null,
};
}).ToList();