Reputation: 569
(no, not the french girl again!!!)
So...I have two entities with a n-n relationship: "new_produit" and "new_lignecontrat". I need to copy the "new_produit" records of the last "new_lignecontrat" record into the newly created "new_lignecontrat".
The plugin is triggered on Create for new_lignecontrat.
So far, I've written this, but I'm not quite sure bout the steps to follow to copy "new_produit" records...
else if (modeleContrat.Id.Equals (ContratForfaitaire))
{
FetchExpression fetch = new FetchExpression(@"
<fetch distinct='false' mapping='logical'>
<entity name='new_contrats'><link-entity name='" + context.PrimaryEntityName + "' alias='nombreligne' from='new_contratsid' to='new_contratsid'><filter type='and'><condition attribute='new_contratsid' value='" + contrats.Id + "' operator='eq'></condition></filter></link-entity></entity></fetch>");
EntityCollection lines = service.RetrieveMultiple(fetch);
if (lines.Entities.Any())
{
var last = lines.Entities.Last();
if (last.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
{
QueryExpression query = new QueryExpression();
query.EntityName = "new_produit";
query.ColumnSet = new ColumnSet("new_produitid");
Relationship relationship = new Relationship();
// name of relationship between team & systemuser
relationship.SchemaName = "new_new_lignecontrat_new_produit";
RelationshipQueryCollection relatedEntity = new RelationshipQueryCollection();
relatedEntity.Add(relationship, query);
RetrieveRequest request = new RetrieveRequest();
request.RelatedEntitiesQuery = relatedEntity;
request.ColumnSet = new ColumnSet("new_lignecontratid");
request.Target = new EntityReference
{
Id = last.Id,
LogicalName = last.LogicalName
};
RetrieveResponse response = (RetrieveResponse)service.Execute(request);
if (((DataCollection<Relationship, EntityCollection>)(((RelatedEntityCollection)(response.Entity.RelatedEntities)))).Contains(new Relationship("new_new_lignecontrat_new_produit")) && ((DataCollection<Relationship, EntityCollection>)(((RelatedEntityCollection)(response.Entity.RelatedEntities))))[new Relationship("new_new_lignecontrat_new_produit")].Entities.Count > 0)
{
response.Entity.Attributes.Remove("new_produitid");
response["new_lignecontratid"] = new EntityReference(target.LogicalName, target.Id);
Upvotes: 1
Views: 3815
Reputation: 5352
I believe I answered this question partially in response to one of your previous questions, so let's see if my answer this time is any better.
The three steps in this problem, if I understand the problem correctly, is to first get the last new_lignecontrat
record created before the create of the current new_lignecontrat
record, then get all the new_produit
records associated with the last new_lignecontrat
, and finally Associate
each of those new_produit
records with the new new_lignecontrat
record.
For this query, you can use any of the three supported query methods in Dynamics (FetchXml, QueryExpression, and Linq). I prefer Linq as the .First()
method is an easy way to execute an efficient TOP
query (to get your last created new_lignecontrat
record), but you can also use FetchXml and the paging cookie to accomplish the same (not sure about QueryExpression).
You can get the linked new_produit
records using the N:N table and the ID retrieved in step 1.
Once you have the id of the new new_lignecontrat
and the ids of the lastly associated new_produit
records, execute the Associate
method of your IOrganizationService
against these records and their relationship. Below is a mockup that handles these three steps.
using (OrganizationServiceContext osc = new OrganizationServiceContext(service))
{
//assumes early binding, but this can be modified for late binding as well
Guid ligneContratID = (from lc in osc.CreateQuery<new_ligneContrat>()
where lc.CreatedOn < (DateTime)targetEntity.Attributes["CreatedOn"] //look at all new_ligneContrat records created before the newly created record
orderby lc.CreatedOn descending //sort newest to oldest
select lc.new_ligneContratID)
.First(); //get the newest record
var produits = from lcp in osc.CreateQuery<new_new_lignecontrat_new_produit>() //use your N:N relationship/table as your linking table
join p in osc.CreateQuery<new_produit>() on lcp.new_produitId equals p.new_produitId
where lcp.new_lignecontratId = ligneContratID //use the previous query result in your N:N lookup
select p.new_produitId;
EntityReferenceCollection erc = new EntityReferenceCollection();
foreach (var e in produits)
{
erc.Add(new EntityReference("new_produit", e));
}
service.Associate("new_lignecontrat", targetEntity.Id, new Relationship("new_new_lignecontrat_new_produit", erc);
}
Upvotes: 3