如何检查关系是否已经存在?

时间:2014-05-08 10:46:35

标签: c# duplicates dynamics-crm-2011 relationships

在我的CRM中,我有一个"顾问"与"联系人"相关的实体具有N:N关系的实体。创建Advisor实体后,我将Advisor与联系人关联,并使用以下代码:

_service.Associate("contact", contactid, relationship, relatedAdvisors);

relatedAdvisors是实体参考集合。但是,如果关系已存在,我会收到错误

  

"无法插入重复的密钥"

如何检查此顾问是否已与联系人相关?

3 个答案:

答案 0 :(得分:2)

以下查询应该适合您。但是我没有编译它,但你可以得到一个想法。

// Create new object of RelatedAdvisors
var newRelatedAdvisors = new new_RelatedAdvisors();

// Go through all the advisors in colletion
foreach(var advisor in relatedAdvisors)
{
    // Search of existing relationship between contact and advisor
    var existingAdvisor = (from a in linqContext.CreateQuery<new_RelatedAdvisors>() where a.contactid ==   contactid && a.Id == advisor.Id select a).FirstOrDefault();

    // if relationship does not exist then add add advisor to newly created collection object
    if(xyz == null || xyz.Count() == 0)
    {
        // Add advisor to newRelatedAdvisors 
    }
}
// associate the contact with newly created collection of relatedadvisors
_service.Associate("contact", contactid, relationship, newRelatedAdvisors);

注意

我没有编译此代码,因为目前我无法访问开发系统。但它可能会帮助你获得一个想法。

答案 1 :(得分:1)

希望这会有所帮助:

private static bool RelationshipExists(IOrganizationService service, string relationshipname, Guid entity1Id, string entity1Name, Guid entity2Id, string entity2Name)
{
    string relationship1EtityName = string.Format("{0}id", entity1Name);
    string relationship2EntityName = string.Format("{0}id", entity2Name);

    //This check is added for self-referenced relationships
    if (entity1Name.Equals(entity2Name, StringComparison.InvariantCultureIgnoreCase))
    {
        relationship1EtityName = string.Format("{0}idone", entity1Name);
        relationship1EtityName = string.Format("{0}idtwo", entity1Name);
    }

    QueryExpression query = new QueryExpression(entity1Name) { ColumnSet = new ColumnSet(false) };

    LinkEntity link = query.AddLink(relationshipname, 
    string.Format("{0}id", entity1Name), relationship1EtityName);

    link.LinkCriteria.AddCondition(relationship1EtityName, 
    ConditionOperator.Equal, new object[] { entity1Id });

    link.LinkCriteria.AddCondition(relationship2EntityName, 
    ConditionOperator.Equal, new object[] { entity2Id });

    return service.RetrieveMultiple(query).Entities.Count != 0;
}

答案 2 :(得分:0)

基于@Saddam Khan提供的代码,这是我想出的。这样可以从relatedEntities集合中排除已关联的实体,并始终将任何数量的实体与两个请求关联/取消关联(第一次检查它们是否已被暗杀,第二个请求没有被关联)。

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;

public static class OrganizationServiceExtension
{
    public static void AssociateIfDisassociated(this IOrganizationService service, EntityReference entity, string relationshipName, string relationshipEntityName, EntityReferenceCollection relatedEntities)
    {
        List<EntityReference> unrelatedEntities = relatedEntities.Except(service.RetrieveRelated(entity, relationshipEntityName, relatedEntities)).ToList();
        if (!unrelatedEntities.Any())
        {
            return;
        }
        service.Associate(entity.LogicalName, entity.Id, new Relationship(relationshipName), new EntityReferenceCollection(unrelatedEntities));
    }

    public static void DisassociateIfAssociated(this IOrganizationService service, EntityReference entity, string relationshipName, string relationshipEntityName, EntityReferenceCollection relatedEntities)
    {
        List<EntityReference> realRelatedEntities = relatedEntities.Intersect(service.RetrieveRelated(entity, relationshipEntityName, relatedEntities)).ToList();
        if (!realRelatedEntities.Any())
        {
            return;
        }
        service.Disassociate(entity.LogicalName, entity.Id, new Relationship(relationshipName), new EntityReferenceCollection(realRelatedEntities));
    }

    public static EntityReferenceCollection RetrieveRelated(this IOrganizationService service, EntityReference entity, string relationshipEntityName, EntityReferenceCollection checkIfRelatedEntities)
    {
        var relatedEntities = new EntityReferenceCollection();
        if (checkIfRelatedEntities?.Any() != true)
        {
            return relatedEntities;
        }

        string relatedEntityLogicalName = checkIfRelatedEntities.First().LogicalName;
        string entityIdFieldName = $"{entity.LogicalName}id";
        string relatedEntityIdFieldName = $"{relatedEntityLogicalName}id";

        //This check is added for self-referenced relationships
        if (entity.LogicalName.Equals(relatedEntityLogicalName, StringComparison.InvariantCultureIgnoreCase))
        {
            entityIdFieldName = $"{entity.LogicalName}idone";
            relatedEntityIdFieldName = $"{relatedEntityLogicalName}idtwo";
        }

        var relatedEntitiesQuery = new QueryExpression(relatedEntityLogicalName) 
        { 
            ColumnSet = new ColumnSet(relatedEntityIdFieldName),
            LinkEntities =
            {
                new LinkEntity
                {
                    LinkToEntityName = relationshipEntityName,
                    LinkFromAttributeName = $"{relatedEntityLogicalName}id",
                    LinkToAttributeName = relatedEntityIdFieldName,
                    LinkCriteria =
                    {
                        Conditions = 
                        { 
                            new ConditionExpression(entityIdFieldName, ConditionOperator.Equal, entity.Id),
                            new ConditionExpression(relatedEntityIdFieldName, ConditionOperator.In, checkIfRelatedEntities.Select(e => e.Id).ToArray())
                        }
                    }
                }
            }
        };
        List<EntityReference> relatedEntitiesList = service.RetrieveMultiple(relatedEntitiesQuery).Entities
            .Select(e => e.ToEntityReference())
            .ToList();
        relatedEntities.AddRange(relatedEntitiesList);
            
        return relatedEntities;
    }
}

System User-Security RoleSystem User-Team的用法示例:

var user = new EntityReference(SystemUser.EntityLogicalName, Guid.NewGuid());
service.AssociateIfDisassociated(
    user,
    "systemuserroles_association",
    SystemUserRoles.EntityLogicalName,
    new EntityReferenceCollection { new EntityReference(Role.EntityLogicalName, Guid.NewGuid()) });
service.AssociateIfDisassociated(
    user,
    "teammembership_association",
    TeamMembership.EntityLogicalName,
    new EntityReferenceCollection { new EntityReference(Team.EntityLogicalName, Guid.NewGuid()) });