2009-02-09 11 views
14

Comment écrire une sous-sélection dans LINQ.Linq Sous-sélection

Si j'ai une liste de clients et une liste de commandes, je veux tous les clients qui n'ont pas de commandes.

Ceci est mon code pseudo tentative:

var res = from c in customers 
where c.CustomerID ! in (from o in orders select o.CustomerID) 
select c 

Répondre

22

Que diriez-vous:

var res = from c in customers 
      where !orders.Select(o => o.CustomerID).Contains(c.CustomerID) 
      select c; 

Une autre option consiste à utiliser:

var res = from c in customers 
      join o in orders 
       on c.CustomerID equals o.customerID 
       into customerOrders 
      where customerOrders.Count() == 0 
      select c; 

Utilisez-vous LINQ to SQL ou autre chose, btw ? Différentes saveurs peuvent avoir des « meilleurs » façons de le faire

+0

n'utilise pas() au lieu du comte() un peu mieux en termes de lisibilité? Était en train de lire le C# plus efficace de Bill Wagner et c'était l'une des recommandations. –

+2

Oui, très probablement. Beaucoup de façons de le faire. Sans doute serait-il bien d'avoir une méthode d'extension Empty() ou None() qui est l'opposé de Any() aussi ... –

+0

Ouais, bonne idée. –

7

Si ceci est la base de données adossés, essayez d'utiliser les propriétés de navigation (si vous les avez définis):

var res = from c in customers 
      where !c.Orders.Any() 
      select c; 

Sur Northwind, cela génère la TSQL:

Qui fait le travail plutôt bien.

-2
var res = (from c in orders where c.CustomerID == null 
       select c.Customers).ToList(); 

ou Faire exception()

-1
  var result = (from planinfo in db.mst_pointplan_info 
                  join entityType in db.mst_entity_type 
                  on planinfo.entityId equals entityType.id 
                  where planinfo.entityId == entityId 
                  && planinfo.is_deleted != true 
                  && planinfo.system_id == systemId 
                  && entityType.enity_enum_id == entityId 
                  group planinfo by planinfo.package_id into gplan 
                  select new PackagePointRangeConfigurationResult 
                  { 
                   Result = (from planinfo in gplan 
                     select new PackagePointRangeResult 
                     { 
                      PackageId = planinfo.package_id, 
                      PointPlanInfo = (from pointPlanInfo in gplan 
                           select new PointPlanInfo 
                           { 
                            StartRange = planinfo.start_range, 
                            EndRange = planinfo.end_range, 
                            IsDiscountAndChargeInPer = planinfo.is_discount_and_charge_in_per, 
                            Discount = planinfo.discount, 
                            ServiceCharge = planinfo.servicecharge, 
                            AtonMerchantShare = planinfo.aton_merchant_share, 
                            CommunityShare = planinfo.community_share 
                           }).ToList() 
                     }).ToList() 
                  }).FirstOrDefault(); 
+1

Ajouter une explication –