3
votes

Hi StackOverflow community,

I just try to copy records of the "contact"- Entity from a Plugin or a custom workflow activity. The relevant Code is

            QueryExpression qe = new QueryExpression("contact")
            {
                ColumnSet =  new ColumnSet("firstname", "lastname")
            };
            EntityCollection entityCollection = _organizationService.RetrieveMultiple(qe);
            foreach (Entity entity in entityCollection.Entities)
            {
                entity.Id = Guid.NewGuid();

                if (!entity.Attributes.Contains("firstname"))
                {
                    entity.Attributes.Add("firstname", "");
                }
                entity["firstname"] = (entity.GetAttributeValue<string>("firstname") ?? "") + "(Copy)";

                _organizationService.Create(entity);
            }

Unfortunately, I'm getting always the error message

"Entity Id must be the same as the value set in property bag".

If I leave out the line

Entity.Id = Guid.NewGuid();

then I'm getting the error

"Cannot insert duplicate key."

I also tried various other ways to construct a new Guid, including

byte [] bytes = new byte[16];
random.NextBytes(bytes);
entity.Id = new Guid(bytes);

or

entity.Id = Guid.Empty;

resulting also in

"Entity Id must be the same as the value set in property bag".

On the other hand, I have a desktop app where I connect to my Microsoft CRM 2016 Office 365 System with the help of this article https://msdn.microsoft.com/en-us/library/jj602970.aspx and can copy records all right.

Any help is greatly appreciated.

1
I think you create a plugin in microsoft dynamic crm you need to register a plugin for create,update and so on and not need to _organizationService.Create(entity); .Akram Khan

1 Answers

6
votes

The QueryExpression always returns the id, both as the actual Entity.Id, and it's property name contactid. That is why you are getting the error. You could just remove this attribute, but best practice is to always create a new C# Contact object, rather than updating one being retrieved from CRM. Also, you don't want to be setting your own GUID, since CRM uses sequential GUIDS that are better optimized for indexing and ordering.

QueryExpression qe = new QueryExpression("contact")
{
    ColumnSet =  new ColumnSet("firstname", "lastname")
};

foreach (Entity entity in _organizationService.RetrieveMultiple(qe).Entities)
{
    var copy = new Entity();
    copy["firstname'] = (entity.GetAttributeValue<string>("firstname") ?? "") + "(Copy)";
    _organizationService.Create(copy);
}