я следующие таблицы сопоставляются с Entity Framework:комплекс LINQ 'Любой' запрос
счетов-фактур (InvoiceID, INVOICENUMBER, IsPaid)
частей (PartID, PARTNUMBER, OrganisationID, IsActive)
Invoices_Parts (InvoiceID, PartID , Количество, IsClaimed)
Я пытаюсь получить List
из InvoiceIDs из таблицы Invoices_Parts
с рядом условий. Условие, с которым у меня проблема, есть «где любойPart
от Invoices_Parts
is active».
код до сих пор:
IQueryable<int> partIds = db.Parts.Where(x =>
x.OrganisationID == loggedInUser.OrganisationID).Select(y => y.PartID);
// && x.IsActive
List<string> invoiceIds = db.Invoices_Parts.Where(x =>
!x.IsClaimed && x.Invoice.IsPaid && partIds.Contains(x.PartID)
.DistinctBy(y => y.InvoiceID)
.Select(z => z.InvoiceID.ToString()).ToList();
Я закомментирована «& & x.IsActive», потому что я хочу, чтобы список InvoiceIDs быть таким, что по крайней мере одна часть должна удовлетворять условию IsActive - I не хотите отфильтровывать все части, где IsActive является ложным. Как достичь этого в LINQ без ручного управления коллекциями и добавления/удаления элементов?
Примечание: В случае, если кто-то интересно, я использую следующий вспомогательный метод для DistinctBy
:
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
Редактировать: У меня есть следующие свойства на каждой сущности:
счета-фактуры :
public virtual ICollection<Invoices_Parts> Invoices_Parts { get; set; }
Часть:
public virtual ICollection<Invoices_Parts> Invoices_Parts { get; set; }
Invoices_Parts:
public virtual Invoice Invoice { get; set; }
public virtual Part Part { get; set; }
У вас есть свойства навигации в ваших сущностях? –
Возможно, вы знаете об этом, но я должен указать, что ваш IQueryable будет срабатывать, когда он дойдет до 'foreach' в вашем расширении' DistinctBy'. Я бы сказал, что для большей ясности вы должны поместить 'ToList()' перед вызовом 'DistinctBy()' в цепочке, чтобы четко указать, где находится запрос. –
@GeorgeMauer Добавление «ToList» безошибочно оценивает весь запрос немедленно, заставляет весь результат быть оцененным и имеет накладные расходы на создание/заполнение списка, который будет полностью проигнорирован. 'AsEnumerable' выполняет желаемую семантику удобочитаемости без каких-либо дополнительных накладных расходов. – Servy