C# LINQ join with conditional where clause on two different data sets
我有两个集合要与之比较数据。我可以通过ID加入这两个集合。我需要有一个WHERE子句,它返回集合A中找不到集合B中某些项的数据列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class Contract { public string ContractId { get; set; } public IList InvoiceList { get; set; } public class Invoice { public int InvoiceNumber { get; set; } } } public class PaymentRequest { public IList Contracts { get; set; } public class ContractList { public string ContractId { get; set; } public IList Invoices { get; set; } } public class InvoiceList { public int InvoiceNumber { get; set; } } } |
到目前为止,我有以下几点,但还不能完全理解WHERE子句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var query = ( from request in ( from contract in paymentRequest.Contracts from invoice in contract.Invoices select new { contract, invoice }) join valid in ( from contract in validContracts select new { contract }) on new { request.contract.ContractId } equals new { valid.contract.ContractId } where !( // get a list of invoice numbers in the request data set that are not in the valid data set ) select"Contract Id:" + request.contract.ContractId + ", Invoice Number:" + request.invoice.InvoiceNumber ).ToList(); |
感谢您的帮助。
1 2 3 | var collectionAIds = new HashSet<int>(collectionA.Select(colAItem => colAItem.Id)); var itemsInCollectionBNotInCollectionA = collectionB.Where(colBItem => !collectionAIds.Contains(colBItem.Id)); |
基本上,我们要获取集合A中的ID,然后从集合B中选择所有项,而不是A的ID列表中。
哈希集是可选的。如果不使用该变量,它只会避免重复的O(N)查找。
P.S.我假设int是ID的类型。为哈希集使用ID的数据类型。
在我看来,您的查询应该如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var query = ( from request in ( from contract in paymentRequest.Contracts from invoice in contract.Invoices select new { contract, invoice } ) join valid in ( from contract in validContracts select new { contract } ) on new { request.contract.ContractId } equals new { valid.contract.ContractId } into gvs where gvs .SelectMany(gv => gv.contract.Invoices) .Select(i => i.InvoiceNumber) .All(n => n != request.invoice.InvoiceNumber) select"Contract Id:" + request.contract.ContractId + ", Invoice Number:" + request.invoice.InvoiceNumber ).ToList(); |
与提醒常规SQL查询的功能相比,使用
1 2 3 4 5 | var result = from itm1 in Coll1 from itm2 in Coll2.Where(x => x.Id == itm1.Id).DefaultIfEmpty() where itm2 == null select itm1; |
这将为您提供列2中不存在的