use*_*119 2 c# linq entity-framework
我有以下表与实体框架映射:
发票(InvoiceID,InvoiceNumber,IsPaid)
部件(PartID,PartNumber,OrganisationID,IsActive)
Invoices_Parts(InvoiceID,PartID,Quantity,IsClaimed)
我试图List从Invoices_Parts表中获得一个具有许多条件的InvoiceID .我有一个问题的条件是"凡任何 Part来自Invoices_Parts处于活动状态".
到目前为止的代码:
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();
Run Code Online (Sandbox Code Playgroud)
我已经注释掉了"&& x.IsActive",因为我希望InvoiceID列表至少有一部分必须符合IsActive条件 - 我不想过滤掉IsActive为false的所有部分.如何在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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我在每个实体上都有以下属性:
发票:
public virtual ICollection<Invoices_Parts> Invoices_Parts { get; set; }
Run Code Online (Sandbox Code Playgroud)
部分:
public virtual ICollection<Invoices_Parts> Invoices_Parts { get; set; }
Run Code Online (Sandbox Code Playgroud)
Invoices_Parts:
public virtual Invoice Invoice { get; set; }
public virtual Part Part { get; set; }
Run Code Online (Sandbox Code Playgroud)
人们经常使LINQ查询过于复杂,因为他们习惯于考虑SQL表,连接等.通常,如果您将实际需求放在简单的英语中,您可以提出一个更简单的查询,它几乎完全相同.
我想要一张付款发票中的发票ID列表,其中该发票上的任何部分都是有效的,等等......等等.
这个怎么样:
from invoice in db.Invoices
where invoice.IsPaid
where invoice.Invoices_Parts.Any(ip => !ip.IsClaimed &&
ip.Part.IsActive &&
ip.OrganisationID == loggedInUser.OrganisationID)
select invoice.InvoiceId
Run Code Online (Sandbox Code Playgroud)
或者如果您更喜欢方法语法:
db.Invoices.Where(i => i.IsPaid)
.Where(i => i.Invoices_Parts.Any(ip => !ip.IsClaimed &&
ip.Part.IsActive &&
ip.OrganisationID == loggedInUser.OrganisationID)
.Select(i => i.InvoiceId)
.ToList();
Run Code Online (Sandbox Code Playgroud)
PS - .ToString()如果你愿意,你可以做一个,但根据我的经验,保留ID强烈输入是明智之举.
PPS - 你可以创建一个DistinctBy方法,它可以很好地与Entity Framework一起使用(不强制过早评估),如下所示:
public static IQueryable<TSource> DistinctBy<TSource, TKey>(this IQueryable<TSource> source, Excpression<Func<TSource, TKey>> keySelector) {
return source.GroupBy(keySelector).Select(i => i.FirstOrDefault());
}
Run Code Online (Sandbox Code Playgroud)