2015-03-23 2 views
1

У меня есть класс BillingProvider, который содержит список претензий. Отдельно у меня есть список номеров претензий, содержащих ошибки. Я хочу исключить претензии с ошибками и, если все претензии в отношении любого BillingProvider имеют ошибки, тогда исключить BillingProvider тоже. Я создал упрощенный макет ситуации. Запрос LINQ ниже исключает ошибки, но возвращает BillingProvider несколько раз.LINQ to Objects filtering

class Program 
{ 
    class BillingProvider 
    { 
     internal string TaxId { get; set; } 
     internal List<Claim> Claims = new List<Claim>(); 
    } 

    class Claim 
    { 
     internal int ClaimNumber { get; set; } 
     internal string ClaimDescr { get; set; } 
    } 

    private static void Main() 
    { 
     var allBillingProviders = new List<BillingProvider> 
     { 
      new BillingProvider 
      { 
       TaxId = "123456789", 
       Claims = new List<Claim> 
       { 
        new Claim {ClaimNumber = 1, ClaimDescr = "First Claim"}, 
        new Claim {ClaimNumber = 2, ClaimDescr = "Second Claim"}, 
        new Claim {ClaimNumber = 3, ClaimDescr = "Third Claim"} 
       } 
      }, 

      new BillingProvider 
      { 
       TaxId = "", 
       Claims = new List<Claim> 
       { 

        new Claim{ClaimNumber = 4, ClaimDescr = "Fourth Claim"}, 
        new Claim{ClaimNumber = 5, ClaimDescr = "Fifth Claim"}, 
        new Claim{ClaimNumber = 6, ClaimDescr = "Sixth Claim"}, 
        new Claim{ClaimNumber = 7, ClaimDescr = "Seventh Claim"}, 
        new Claim{ClaimNumber = 8, ClaimDescr = "Eighth Claim"} 
       } 
      } 
     }; 


     // Set up errors 
     var errors = new List<int> {2, 5}; // Claims 2 and 5 have erros and should be excluded 


     var bpClaims = (from b in allBillingProviders 
         from c in b.Claims 
         where (!errors.Contains(c.ClaimNumber)) 
         select b).ToList(); 

     foreach (var bpc in bpClaims) 
      Console.WriteLine("Count of claims in {0} is {1}", bpc.TaxId, bpc.Claims.Count); 
     Console.ReadLine(); 
    } 

}

+0

Что граф вы хотите, чтобы вернуться на «123456789» .. 3 или 2? – entropic

ответ

5

Я хотел бы сделать это в два этапа:

var bpClaims = 
    allBillingProviders.Select(x => new BillingProvider() 
     { 
     TaxId = x.TaxId, 
     Claims = x.Claims.Where(c => !errors.Contains(c.ClaimNumber)).ToList() 
     }) 
    .Where(x => x.Claims.Any()) 
    .ToList(); 
+0

Спасибо, что работает. Мой класс BillingProvider имеет намного больше полей, чем в примере, мне нужно снова отобразить ВСЕ поля? – AnnieMacD

+1

Я бы подумал об использовании [Automapper] (http://automapper.org/), но если объектов много, а полей тоже много, накладные расходы на все эти копии должны быть, вероятно, учтены. Может быть, избавиться от LINQ и сделать простой 'foreach' на провайдерах, исправлять (удалять) претензии? –

+0

Я уже сделал это - было только около 12 полей, и я думаю, что накладные расходы будут минимальными. Прекрасно работает! – AnnieMacD

1

Один из способов использования различных, но так как вы можете отличаются от ClaimNumber, так как я думаю, номер претензии не будет повторяться вы можете использовать эту библиотеку, которая имеет DistictBy

https://code.google.com/p/morelinq/

var bpClaims = (from b in allBillingProviders 
         from c in b.Claims 
         where (!errors.Contains(c.ClaimNumber)) 
         select b).DistinctBy(c=>c.ClaimNumber).ToList(); 
1

Вы можете получить количество идентификаторов претензий, не включая идентификаторы исковые ошибок, выполнив это в Console.WriteLine линии:

Console.WriteLine("Count of claims in {0} is {1}", bpc.TaxId, bpc.Claims.Select(x=> x.ClaimNumber).ToList().Except(errors).Count()); 
+0

Спасибо, но мой тестовый выход в консоли - это только тестовый выход. Меня интересуют сами объекты! – AnnieMacD

+0

Ах, вы! Рад, что у вас есть решение! –