I have two system entities: invoice and invicedetail.
In system exist association 1:N - invoice_details (parent: invoice, child: invoicedetail).
I go to invoice details, next go to Products section (invoicedetail) and add new product. Now this product and invoice is associate but my plugin not triggered ;/
I registered my plugin on associate (parent and child entity are empty in plugin registration tool, execution is POST-Operation).
Code:
if(context.Message == "Associate")
{
//but plugin not go here - it's not trigger on associate ;/
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
{
entityRef = (EntityReference)context.InputParameters["Target"];
entity = service.Retrieve("invoice", entityRef.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet("invoiceid", "numberOfSomething"));
}
else
{
throw new Exception("excep");
}
}
I believe associate is used for many to many. Try registering your plugin on the update and create of invoicedetail. You will probably want to add filtering attributes to the update so it only fires when the invoice lookup on the invoicedetail changes. Then add a check to only perform your logic when the invoice lookup is set.
Related
I'm aiming to show virtual entity records on a subgrid on the form of a custom entity (say, Client). I have created a virtual entity, custom data provider and registered the required plugin. So far things work fine; I load the form, subgrid loads with the data from external webservice.
Now, I want to pass a string field on the form (say, Client.ExternalId) as a parameter to the retrieveMultiple plugin so that I can use this field to query the datasource.
The retriveMultiple plugin steps (registered automatically when custom data provider was set up) show that it was registered on the virtual entity and not Client entity. Since it gets executed on load of the subgrid on the Client entity form I am not sure how I can pass a field to the plugin.
Can someone please give some guidance on how to achieve this?
Version 1710 (9.2.22103.194) online
Thanks
If the virtual entity has an N:1 relationship with the main entity and the subgrid is configured to show related records, then you can do like this:
// first, get the whole query
var query = context.InputParameterOrDefault<QueryExpression>("Query");
// next, get the linkEntity and then the linkFilter
var linkFilter = query.LinkEntities.FirstOrDefault(x => x.LinkToEntityName == "mainEntityLogicalName").LinkCriteria;
// next, get the main entity id
var mainEntityId = linkFilter.Conditions.FirstOrDefault(x => x.AttributeName == "mainEntityIdFieldName").Values.FirstOrDefault() as Guid?;
// finally, retreive main entity to get the Client.ExternalId
var mainEntity = orgSvc.Retrieve("mainEntityLogicalName", mainEntityId.Value, new ColumnSet("Client.ExternalId"));
var clientExternalId = mainEntity.GetAttributeValue<string>("Client.ExternalId");
I'm trying to create a basic Salesforce apex trigger based off the Zendesk Ticket sObject, in order to update a boolean on a lead. This is my first Salesforce trigger, so there might be some basic steps I'm missing.. But I've saved the trigger in the Developer Console and it doesn't report any problems, yet creating a new ticket doesn't update the boolean.
Here's the trigger I'm running below. I've installed the Zendesk integration onto my Developer edition Salesforce, to the point that new tickets display on a lead's record. However when I have this trigger active and log a new ticket with a lead, it doesn't update the boolean.
trigger UpdateCampaignResponse on Zendesk__Zendesk_Ticket__c (after insert) {
for(Zendesk__Zendesk_Ticket__c ticket : Trigger.new) {
// Check if ticket requester is a lead
if(String.valueOf(ticket.Zendesk__Requester__c).startsWith('00Q')== True) {
// Create a set, add ticket requester id
set<id>leadId=new set<id>();
leadId.add(ticket.Zendesk__Requester__c);
// Lookup and assign lead based on set
Lead lead=[Select CampaignResponse__c from Lead where id in :leadId];
// Mark Campaign Response on lead
lead.CampaignResponse__c=True;
update lead;
}
}
}
I use Breeze in my asp.net application with the Durandal SPA template.
I need to add an entity to the saveMap which already exists in DB.
Let's take this simple example: the page display an invoice and the invoice's lines. The user add a new invoice's line and click the save button. The SaveChanges controller's action is triggered with ONLY the modified invoice's line. Server side, the total is recalculated and the invoice's total must be modified. But this total is located on the invoice entity so we need to add the invoice's entity to the saveMap.
I found a way to proceed to add a new entity to the saveMap here: Breeze BeforeSaveEntities: how to modify savemap
But the suggested solution is used to add a new entity to the saveMap (Added state) which will create a new record on DB. This is not what I need. I need to add a new entity to the saveMap which (Modified state) will be get the data from DB.
I tried like this:
int invoiceId = 1234;
dc.Configuration.ProxyCreationEnabled = false; // don't forget this!
EFContextProvider<BreezeContext> cp = new EFContextProvider<BreezeContext>();
var acc = dc.Invoices.Where(x => x.Id == invoiceId).FirstOrDefault();
ei = cp.CreateEntityInfo(acc, Breeze.WebApi.EntityState.Modified);
invoices = new List<EntityInfo>();
saveMap.Add(typeof(Invoice), invoices);
invoices.Add(ei);
So far so good.
Then I need to add the total property to the OriginalValuesMap (otherwise modification will not be updated):
ei.OriginalValuesMap.Add("TotalExclVAT", invoice.TotalExclVAT);
**This don't work: ei.OriginalValuesMap is null and so I cannot add a new key inside.
I don't know if this is the right way to proceed. Hope my explanations are clear enough.
Thanks for your help.
UPDATE
As suggested by Jay:
ei.ForceUpdate = true;
No need to take care of OriginalValuesMap in this case.
I haven't yet had a chance to dig into this yet, but have you looked at the EntityInfo.ForceUpdate property.
This property may be used to force a server side update of an entire entity when server side modification has been made to an existing entity. May be used in place of explicitly updating the EntityInfo.OriginalValuesMap.
So far we've only documented this in the release notes so it's understandable how it might be missed.
I've just started working with Web API this week, and I'm struggling with something which I think should be quite simple, but haven't been able to find the answer for yet. Perhaps I'm searching using the wrong terms.
One of the calls to the API passes through a GUID. I need to create a new entity (using Entity Framework) and set one of the relations to this newly passed in GUID. This GUID is the ID of a different entity in the database.
I'm struggling to attach the entity via the relation without fetching the whole entity too.
For example,
public void DoWork(IList<Guid> userGuids)
{
Order order = new Order() // This is an entity
{
CreateDate = DateTime.Now,
CreatedBy = "Me",
Items = (from i in this.Model.Items
where i.Id == userGuid
select i).ToList<Item>();
}
Model.Orders.Add(order);
Model.SaveAll();
}
In the above, I have to do a database call to attach the Item entities to the Order. Is there not a way around this? Seems very redundant to retrieve the whole entity objects when I only require their IDs (which I already have anyway!)!
One solution is stub entities as asked here: Create new EF object with foreign key reference without loading whole rereference object
Link to the source blog referenced: http://blogs.msdn.com/b/alexj/archive/2009/06/19/tip-26-how-to-avoid-database-queries-using-stub-entities.aspx
Snip from the blog - to be applied to your situation:
Category category = new Category { ID = 5};
ctx.AttachTo(“Categories”,category);
Product product = new Product {
Name = “Bovril”,
Category = category
};
ctx.AddToProducts(product);
ctx.SaveChanges();
This way (in the example) the Product is saved without ever loading the Category object.
I am using the Entity framework to create a new order. The order contains a collection of contacts, a many to many relationship. I want to add a reference to an existing contact on the order on creation of the order. Both Order and Contact a Entity Objects.
Order order = new Order();
//set details on order
Contact contact = new Contact();
EntityKey contactKey =
new EntityKey("OrderDetails.Contact",
"contact_id", contact.Key.Id);
contact.EntityKey = contactKey;
contact.contact_id = contact.Key.Id;
order.Contact.Attach(contact); // throws an exception!
OrderDetails ordTable = new OrderDetails();
ordTable.AddToOrder(order);
int result = orgTable.SaveChanges();
When I go to attach, this exception is thrown:
"Attach is not a valid operation when the source object associated with this related end is in an added, deleted, or detached state. Objects loaded using the NoTracking merge option are always detached."
I know I'm probably missing a step or not fully understanding how the entity framework handles many-to-many relationships.
"Attach" is not allowed because you haven't saved the order yet. Calling "Add" tells Entity Framework that you want to insert a new contact. So you are left with only one option. You need to load the contact.
Here's the fastest way to do that:
OrderDetails context = new OrderDetails();
Contact contact = context.GetObjectByKey(new EntityKey("OrderDetails.Contact", "contact_id", existingContactId));
order.Contact.Add(contact);
If Order has a property Contact, then you can do:
order.Contact.Add(contact);
I would suggest making the property called Contacts rather than Contact, though.