C#LINQ与两个不同数据集上的条件where子句连接

时间:2016-02-19 21:43:24

标签: c# .net linq

我有两个我正在比较数据的集合。我可以通过ID加入这两个集合。我需要一个where子句,它返回一个数据列表,其中集合B中的某些项目未在集合A中找到

    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子句。

    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();

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

var collectionAIds = new HashSet<int>(collectionA.Select(colAItem => colAItem.Id));
var itemsInCollectionBNotInCollectionA = collectionB.Where(colBItem => 
                                             !collectionAIds.Contains(colBItem.Id));

基本上,我们想要在集合A中获取ID,然后从集合B中选择所有项目,而不是在A的ID列表中。

HashSet是可选的。如果你不使用那个变量,它只是避免重复的O(n)查找。

P.S。我假设int,作为id的类型..使用Hashset的id的数据类型。

答案 1 :(得分:0)

使用contains使得性能低于提醒常规Sql查询的性能。这会更好

var result = 
    from itm1 in Coll1
    from itm2 in Coll2.Where(x => x.Id == itm1.Id).DefaultIfEmpty()
    where itm2 == null
    select itm1;

这将为您提供Coll1中Coll2中不存在的所有项目。这比任何时候使用Contains要快

答案 2 :(得分:0)

在我看来,您的查询应如下所示:

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();