У меня есть две коллекции, с которыми я сравниваю данные. Я могу присоединиться к двум коллекциям по идентификаторам. Мне нужно иметь предложение 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();

Любая помощь приветствуется.

2
I collect Internet points 20 Фев 2016 в 00:43

3 ответа

Лучший ответ
var collectionAIds = new HashSet<int>(collectionA.Select(colAItem => colAItem.Id));
var itemsInCollectionBNotInCollectionA = collectionB.Where(colBItem => 
                                             !collectionAIds.Contains(colBItem.Id));

В основном, мы хотим получить идентификаторы в коллекции A, а затем выбрать все элементы из коллекции B, а не в списке идентификаторов A.

HashSet не является обязательным. он просто избегает повторяющихся поисков O (n), если вы не используете эту переменную.

P.s. Я предполагаю int, как тип идентификатора .. используйте тип данных идентификатора для Hashset.

1
Raja Nadar 19 Фев 2016 в 22:55

Мне кажется, ваш запрос должен выглядеть так:

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();
0
Enigmativity 21 Фев 2016 в 00:23

Использование 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 в любое время

0
T.S. 21 Фев 2016 в 00:01