2012-06-06 1 views
2

J'essaie de sélectionner un ensemble distinct à l'aide d'une requête LINQ to CRM et il continue à renvoyer des enregistrements en double. La requête J'utilise est:Sélection de Distinct à l'aide de LINQ avec CRM

var linqQuery = (from r in gServiceContext.CreateQuery("opportunity") 
        join c in gServiceContext.CreateQuery("account") on ((EntityReference)r["accountid"]).Id equals c["accountid"] 
        join u in gServiceContext.CreateQuery("systemuser") on ((EntityReference)r["ownerid"]).Id equals u["systemuserid"] 
        where (r["statuscode"].Equals("100000004") || r["statuscode"].Equals("100000003")) && r["statecode"].Equals("Open") 
        where u["internalemailaddress"].Equals(_currentUser.Email) 

         select new 
          { 
           AccountId = !c.Contains("accountid") ? string.Empty : c["accountid"], 
           Account = !c.Contains("name") ? string.Empty : c["name"] 
          }).Distinct(); 

Suis-je manque quelque chose à faire .Distinct() travail? Ou y a-t-il une meilleure façon de le faire?

+0

Est-ce CRM 2011? Si c'est le cas, il vaut mieux interroger les ensembles d'entités (accountSet, opportunitySet, etc.) off OrganisationServiceProxy – Alex

+0

'Distinct' utilise simplement le comparateur d'égalité par défaut, qui à son tour utilise' Object.Equals', qui à son tour est lui-même correctement écrasé classes anonymes et les considère simplement égales si toutes les propriétés sont égales. Donc, fondamentalement, votre code semble bien donné un coup d'oeil rapide. Bien sûr, peut-être que le fournisseur LINQ pour CRM ne le fait pas. –

+0

@alex Oui c'est CRM 2011 –

Répondre

1

L'appel Distinct sans un comparateur explicite utilise simplement le comparateur d'égalité par défaut, qui dans le cas des types anonymes se résume à Object.Equals. Cela est remplacé dans les types anonymes pour être égal si toutes les propriétés du type sont égales. Dans ce cas, il vérifiera les propriétés AccountId et Account.

Je suppose que cela fonctionne et que les valeurs sont différentes en termes de cas (comme les chaînes comparent la casse par défaut) ou elles sont en fait distinctes et vous ne pouvez pas le voir.

Heureusement, cela n'a rien à voir avec le fournisseur Linq spécifique à CRM.

1

Utilisez une IEqualityComparer<T> spécifiée: http://msdn.microsoft.com/en-us/library/bb356803

Une autre chose, je ne sais pas si les classes anonymes prennent en charge les implémentations IEqualityComparer<T>.

+0

Ils le font. Le comparateur par défaut délègue à 'Object.Equals' qui est substitué sur les types anonymes pour être égal si toutes les propriétés sont égales. –