3
votes

Impossible de récupérer les enregistrements non partagés

J'ai un scénario, pour trouver les enregistrements qui ne sont pas partagés avec l'équipe d'accès.

QueryExpression query = new QueryExpression("task")
        {
            ColumnSet = new ColumnSet("activityid", "subject", "customid"),
            Criteria = new FilterExpression()
            {
                Conditions =
                {
                    new ConditionExpression("customid", ConditionOperator.NotNull)
                }
            },
            LinkEntities =
            {
                new LinkEntity("task", "principalobjectaccess", "activityid", "objectid", JoinOperator.Inner)
                {
                    Columns = new ColumnSet(true),
                    EntityAlias = "POA",
                    LinkCriteria = new FilterExpression()
                    {
                        Conditions =
                        {
                            new ConditionExpression("principaltypecode", ConditionOperator.NotEqual, "team")
                        }
                    }
                }
            }
        };

Le résultat contient des enregistrements qui sont partagés et non partagés.

La valeur principaltypecode contient soit SystemUser, soit Team, dans mon scénario, j'attends des enregistrements qui ne sont partagés avec aucune équipe.

Mise à jour: strong > XrmToolBox a un plugin qui m'a aidé à trouver des enregistrements non partagés.

entrez la description de l'image ici

 entrez la description de l'image ici a >

Ce plugin a la réponse à ma question mais j'ai besoin d'un code ac # pour ce faire. Quelqu'un connaît-il le mécanisme de cet outil pour trouver de tels enregistrements?


3 commentaires

je suppose que la table POA contient uniquement des enregistrements partagés .....


Il y aura toujours 1 entrée pour chaque enregistrement dans la table POA, car lorsque l'enregistrement est créé, il sera partagé avec l'utilisateur propriétaire. Si nous partageons l'enregistrement avec l'équipe, 1 enregistrement supplémentaire sera créé dans POA. Maintenant, je dois récupérer les enregistrements qui sont partagés avec l'équipe et soustraire de tous les enregistrements de la base de données. C'est la seule issue que je vois ici.


Le plugin @Nachiket XrmToolBox utilise la solution 1 que j'ai publiée dans ma réponse ci-dessous. Vous pouvez le vérifier à l'aide de Fiddler ou d'un autre outil de débogage Web similaire.


3 Réponses :


0
votes

Vous n'avez pas de moyen direct de récupérer des enregistrements qui ne sont pas partagés. Mais ce que vous pourriez faire, c'est

  1. Obtenez principalobjectaccess où en ce qui concerne l'enregistrement est le compte ou le contact ou ainsi de suite
  2. De cette façon, vous aurez tous les comptes / contacts qui sont partagés.
  3. Maintenant, parcourez tous les comptes / contacts et vérifiez que l'identifiant que vous avez récupéré de principalobjectaccess correspond ou non
  4. De cette façon, vous pouvez obtenir une liste ou un compte / contact (enregistrements) qui ne sont pas partagés

     entrez la description de l'image ici


2 commentaires

C'est vrai. Je dois essayer de cette façon. J'ai un grand ensemble de données.


@Nachiket Faites-moi savoir si cela aide à résoudre votre problème.



0
votes

J'ai vérifié la base de données et PrincipleTypeCode est un ObjectTypeCode stocké sous forme de int , plutôt que comme chaîne .

 principalTypeCode

8 est le code de type d'objet pour SystemUser
9 est le code de type d'objet pour Team

principaltypecode ne doit jamais être égal à "team", donc votre requête actuelle renvoie tout.

Vous voudrez peut-être essayer:
new ConditionExpression ("principaltypecode", ConditionOperator.NotEqual, 9)


5 commentaires

Cela ne fonctionne pas. Vous obtiendrez toujours des tâches partagées à la fois avec les utilisateurs et les équipes.


Quelles valeurs sont dans le PrincipalTypeCode? Il ne devrait pas y avoir de 9. Pire encore, vous pouvez les filtrer après la récupération.


Équipe ou utilisateur. Le fait est que si un enregistrement est partagé avec un utilisateur et une équipe, la table POA aura 2 entrées, une pour l'utilisateur et une pour l'équipe. Ainsi, lors de l'utilisation de notequal à 9, la requête récupérera toujours la tâche partagée avec les deux car elle aura une entrée dans la table POA non liée au PrincipalTypeCode 9.


OK, cela a du sens. Je ne suis pas sûr qu'une requête puisse faire ce que vous voulez. Vous envisagez peut-être d'exécuter la requête existante, puis de filtrer davantage le code. Je le fais tout le temps dans les applications de console - récupérer des ensembles de données et les traiter dans la RAM. LINQ est très pratique pour ce type de chose.


Oui, je corrigerai le code. Que faire si je trouve les enregistrements de tâches qui n'ont pas d'entrée dans la table POA? cela fonctionnera-t-il dans mon cas?



0
votes

Solution 1

Effectuez une jointure externe à gauche entre la tâche et la table POA, en récupérant uniquement la colonne acitivityId et la colonne principaltypecode:

        var teamPrincipalTypeCode = 9;

        var query = new QueryExpression("task");

        var principalObjectAccess = query.AddLink("principalobjectaccess", "activityid", "objectid");

        principalObjectAccess.LinkCriteria.AddCondition("principaltypecode", ConditionOperator.Equal, teamPrincipalTypeCode);

        var entityCollection = _service.RetrieveMultiple(query);

Effectuez ensuite un filtrage en mémoire pour supprimer toutes les entrées de la collection où principaltypecode est égal à team. Sachez que si vous trouvez un identifiant qui remplit cette condition, vous devez supprimer toutes les entrées avec cet identifiant, il est important de supprimer les tâches qui sont partagées à la fois avec un utilisateur et une équipe.

Solution 2

Cette requête vous donnera toutes les tâches qui sont partagées avec une équipe:

        var query = new QueryExpression("task");

        var principalObjectAccess = query.AddLink("principalobjectaccess", "activityid", "objectid", JoinOperator.LeftOuter);

        principalObjectAccess.Columns.AddColumns("principaltypecode");

        var entityCollection = _service.RetrieveMultiple(query);

Après l'exécution il vous suffit de rechercher tous les guides de tâche et de soustraire ceux renvoyés par la requête ci-dessus. Vous pouvez facilement le faire en utilisant la méthode Except de l'espace de noms System.Linq.


2 commentaires

Ca a du sens. Son exécution prendra un certain temps et pourrait ne pas être réalisable pour le grand ensemble de données.


@Nachiket Malheureusement, FetchXml n'est pas aussi riche que SQL. En SQL, cela pourrait être fait dans une seule requête imbriquée :)