Retrieve top five opportunities from CRM using C# - dynamics-crm-2011

I have written code for retrieving the Opportunity entity from dynamics CRM, is there any way I can retrieve only top five entities based on the revenue ?

QueryExpression query_ = null;
RetrieveMultipleRequest requests_ = null;
query_ = new QueryExpression();
query_.EntityName = "opportunity";
query_.ColumnSet = new ColumnSet(true);
query_.Orders.Add(new OrderExpression("estimatedvalue", OrderType.Descending));
query_.PageInfo.Count = 5;
query_.PageInfo.PageNumber = 1;
requests_ = new RetrieveMultipleRequest();
requests_.Query = query_;
EntityCollection collection = _sdk.RetrieveMultiple(requests);

In query expression you can set
queryExpression.PageInfo.Count = 5;
Don't forget put a specific order, in a FetchXml you can set like that:
<fetch mapping="logical" count="0" version="1.0">

Related

intersection of search (in diff. fields) - Lucene

I tried following in Lucene 6.2.1:
I have different fields A,B,C,D,E and I make for every field a different searchquery.
Then I want to make a intersection. Show it, when the result is everywhere true.
Someone told me to try this with Booleanquery. So this is my approach:
IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();
BufferedReader in = null;
in = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
QueryParser parser1 = new QueryParser("A", analyzer);// i have 5 different QueryParser
Query qPersonen = parser1.parse("searchstring"); // i have also 5 Queries
booleanQuery.add(qPersonen, BooleanClause.Occur.MUST);
TotalHitCountCollector collector = new TotalHitCountCollector();
TopDocs results = searcher.search(booleanQuery.build(), 100);
ScoreDoc[] hits = results.scoreDocs;
int numTotalHits = results.totalHits;
System.out.println("Results: " + numTotalHits);
Why isn't it working? What could be the fault? It always returns no results :(
As I see your code, It seems that you didn't get instance of BooleanQuery. Since lucene 5, the boolean query's API has been changed. Try the following:
QueryParser parser1 = new QueryParser("A", analyzer);// i have 5 different QueryParser
Query qPersonen = parser1.parse("searchstring"); // i have also 5 Queries
BooleanQuery.Builder bq = new BooleanQuery.Builder();
bq.add(new BooleanClause(aPersonen, BooleanClause.Occur.MUST));
Hope this will work for you :)

Updating DAC Extension

I am trying to update some custom fields in a DAC extension via code, it is not saving the changes to the DB. The code works fine to retrieve the extension and data. What am I missing - do i have to somehow update the myLS with the extension (i thought it did that automatically)?
myLS = LineItemSerial.Select();
INItemLotSerialExt myext = myLS.GetExtension<INItemLotSerialExt>();
myext.UsrFrame1 = "xyz";
myext.UsrFrame2 = "zzz";
myext.UsrFrame3 = "yyy";
LineItemSerial.Update(myLS);
graph.Actions.PressSave();
You should say to cache of Acumatica that you want to update value:
LineItemSerial.Cache.SetValueExt(myLS , "UsrFrame1", "xyz");
LineItemSerial.Cache.SetValueExt(myLS , "UsrFrame2 ", "zzz");
LineItemSerial.Cache.SetStatus(myLS , PXEntryStatus.Modified);
LineItemSerial.Cache.Update(myLS);
LineItemSerial.Cache.IsDirty = true;
NB. LineItemSerial.Cache.IsDirty = true; for some cases can be omitted but in my experience it was often helpful.
INItemLotSerialExt myext = LineItemSerial.GetExtension<INItemLotSerialExt>(myLS); //if LineItemSerial is a view related to the DAC. I hope LineItemSerial is a public view defined in the graph as you are trying to save the changes when u press the save of graph.
OR
INItemLotSerialExt myext = PXCache<INItemLotSerial>.GetExtension<INItemLotSerialExt>(myLS);
Is'nt this the rite way to get the extension?
From documentation
GetExtension(object)
InventoryItem item = cache.Current as InventoryItem;
InventoryItemExtension itemExt =
cache.GetExtension<InventoryItemExtension>(item);
OR
GetExtension(Table)
The code below gets an extension data record corresponding to the given instance of the base data record.
InventoryItem item = cache.Current as InventoryItem;
InventoryItemExtension itemExt =
PXCache<InventoryItem>.GetExtension<InventoryItemExtension>(item);
Try something like this...
ContractExtension cExt = PXCache<PMProject>.GetExtension<ContractExtension>(project);
ARInvoiceEntry graph = PXGraph.CreateInstance<ARInvoiceEntry>();
graph.Document.Current = graph.Document.Search<ARInvoice.projectID, ARInvoice.docDate>(projectID.Value, invoiceDate.Value);
if(graph.Document.Current !=null)
{
ARInvoice i = graph.Document.Current;
i.InvoiceNbr = cExt.CustomerPO;
graph.Document.Update(i);
graph.Actions.PressSave();
}

Microsoft Dynamics Crm Sdk - Is this query possible?

I am exploring the "QueryExpression" mechanism used to Retrieve data via the Dynamics CRM SDK, and I think I have hit a problem / limitiation with the SDK, but I would like to ascertain that for certain..
Given this desired SQL:
Select C.firstname, C.lastname
FROM contact C
INNER JOIN customeraddress A on C.contactid = A.parentid
WHERE
((C.firstname = 'Max' AND C.lastname = 'Planck') OR (C.firstname = 'Albert' AND C.lastname = 'Einstein'))
OR
A.Line1 = 'The secret moonbase'
I cannot appear to translate the filter criteria above (the where clause) into the equivalent SDK conditions / filterexpressions etc.
As you can see, I want to query:-
contact, joined to customeraddress (thats simple, just add a link entity to the query expression),
where the contact is either Albert Einstein, or Max Planck (Again, that is simple, add FilterExpressions to the QueryExpression)
OR the customeraddress 'line1' equals 'the secret moonbase' (This is the problematic bit, as soon as I append filter criteria to the LinkEntity, Dynamics uses an "AND" conjunction with the criteria / filters on the main entity.
So the problem I have described in point 3 above, means I can't query dynamics for:
(Albert Einstein Or Max Planck) or anyone who lives at the secret moonbase.
Is this is a current limtation of the SDK?
Ok, I have discovered the answer to this, thanks in part to #mwrichardsone who prompted me to explore how the Dynamics Crm Linq query provider does it, I was then able to work backwards from there..
So here is the equivalent Linq query expression which works (I am using the CrmOrganisationServiceContext):-
var contactsQuery = from c in orgService.CreateQuery("contact")
join a in orgService.CreateQuery("customeraddress") on (Guid)c["contactid"] equals (Guid)a["parentid"]
where (((string)c["firstname"] == "Max" && (string)c["lastname"] == "Planck")
|| ((string)c["firstname"] == "Albert" && (string)c["lastname"] == "Einstein"))
|| (string)a["line1"] == "The secret moonbase"
select c;
I then found this article which explains how you can convert linq query to a Query Expression or Fetch Xml: http://pogo69.wordpress.com/2012/04/05/crm-linq-provider-converting-expressions-to-queryexpression-andor-fetchxml/
Once i applied that technique I was able to see what the equivalent QueryExpression looks like.. and basically, the bit that I was missing (key insight) is that when you add a ConditionExpression you can set it's "EntityName". This means you can add a ConditionExpression to a filter group thats on the parent / main entity, even though the condition is actually for an attribute thats present on a link entity (in this case customeraddrress line1). I was assuming you had to add the condition to the linkentity that had that particular attribute - which is also what #Henk van Boeijen did in his answer - and that did not give the correct results.
So the final working QueryExpression looks like this (notice the condition for address line 1 is not added to the address link entity, its added to the filter group on the main entity, and it has an "entity name" set to the alias of the link entity)
var orgService = serviceProvider.GetOrganisationService();
using (orgService as IDisposable)
{
var query = new QueryExpression("contact");
query.ColumnSet.AddColumn("firstname");
query.ColumnSet.AddColumn("lastname");
// so link in customer address.
query.AddLink("customeraddress", "contactid", "parentid", JoinOperator.Inner);
var addressLink = query.LinkEntities[0];
addressLink.EntityAlias = "A";
addressLink.IncludeAllColumns();
// conditions for max planck
var firstName1Condition = new ConditionExpression("firstname", ConditionOperator.Equal, "Max");
var lastname1Condition = new ConditionExpression("lastname", ConditionOperator.Equal, "Planck");
// Groups those conditions using an "AND" conjunction.
var maxPlankFilter = new FilterExpression(LogicalOperator.And);
maxPlankFilter.AddCondition(firstName1Condition);
maxPlankFilter.AddCondition(lastname1Condition);
// conditions for albert einstein
var firstname2Condition = new ConditionExpression("firstname", ConditionOperator.Equal, "Albert");
var lastname2Condition = new ConditionExpression("lastname", ConditionOperator.Equal, "Einstein");
// Groups those conditions using an "AND" conjunction.
var albertEinsteinFilter = new FilterExpression(LogicalOperator.And);
albertEinsteinFilter.AddCondition(firstname2Condition);
albertEinsteinFilter.AddCondition(lastname2Condition);
// could optionally chain the 2 filters so we get Albert's contitions chained (using AND) to max's conditions
// albertEinsteinFilter.AddFilter(maxPlankFilter);
// conditions for address line 1 moonbase
var addressLine1Filter = new FilterExpression(LogicalOperator.And);
var line1Condition = new ConditionExpression("A", "line1", ConditionOperator.Equal, "The secret moonbase");
addressLine1Filter.AddCondition(line1Condition);
// add filters to query
// ensures each filter that we add to our queries criteria is chained together using an OR.
query.Criteria.FilterOperator = LogicalOperator.Or;
query.Criteria.AddFilter(albertEinsteinFilter);
query.Criteria.AddFilter(maxPlankFilter);
query.Criteria.AddFilter(addressLine1Filter);
var results = orgService.RetrieveMultiple(query);
int resultCount = 0;
foreach (var r in results.Entities)
{
resultCount++;
Console.WriteLine(string.Format("{0} {1} {2}", (string)r["firstname"], (string)r["lastname"], (string)((AliasedValue)r["A.line1"]).Value));
}
Console.WriteLine("There were " + resultCount + " results..");
}
Side Note: See #Henk van Boeijen's post below if you would like to see a shorter syntax for building a query expression. If productivity is truly your concern however, I would have to echo the comment from #Nicknow below and suggest that you seriously take a look at using the Linq query mechanism for performing CRM queries.
Also #Henk van Boeijen has pointed out that my answer is based on a feature that only appears in the 2013 SDK, and doesn't appear to be in prior versions. I haven't checked this personally, but that information is probably very useful for you to know especially if you are not using the latest versions of the SDK.
It is actually pretty straightforward; use the LogicalOperator and the LinkEntity.
I would recommend adding the DISTINCT predicate.
private IEnumerable<Entity> QueryExpression(IOrganizationService service)
{
var query = new QueryExpression("contact");
query.Distinct = true;
query.ColumnSet.AddColumns("firstname", "lastname");
query.Criteria.FilterOperator = LogicalOperator.Or;
var f1 = query.Criteria.AddFilter(LogicalOperator.And);
f1.AddCondition("firstname", ConditionOperator.Equal, "Max");
f1.AddCondition("lastname", ConditionOperator.Equal, "Planck");
var f2 = query.Criteria.AddFilter(LogicalOperator.And);
f2.AddCondition("firstname", ConditionOperator.Equal, "Albert");
f2.AddCondition("lastname", ConditionOperator.Equal, "Einstein");
var link = query.AddLink("customeraddress", "contactid", "parentid");
link.EntityAlias = "ca";
query.Criteria.AddCondition("ca", "line1", ConditionOperator.Equal, "The secret moonbase");
var response = service.RetrieveMultiple(query);
return response.Entities;
}
It is important to note that this query uses a new feature added in Dynamics CRM 2013. It does not work in Dynamics CRM 2011, because in that version it is not possible to specify an entityname (or its alias) in the ConditionExpression.

Dynamics CRM 2011 LinkEntities left join issue

How can I add a filter condition to the linked entity (for example email in this case)?
Added filter condition to the link criteria which is giving me the duplicate rows.
The equivalent sql query should look like this.
select distinct OpportunityId
from Opportunity o
left join Email e on e.RegardingObjectId = o.OpportunityId
where o.StateCode = 1 and o.StatusCode = 3
and e.RegardingObjectId is null
But the QueryExpression class is doing the following way.
select distinct opportunityid
from Opportunity o
left join Email e
on e.RegardingObjectId = o.OpportunityId
and e.RegardingObjectId is null
where o.StateCode = 1 and o.StatusCode = 3
The code:
ClientCredentials Credentials = new ClientCredentials();
Credentials.Windows.ClientCredential
= System.Net.CredentialCache.DefaultNetworkCredentials;
Uri OrganizationUri = ""
Uri HomeRealmUri = null;
OrganizationServiceProxy orgService
= new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null);
IOrganizationService _service = (IOrganizationService)orgService;
QueryExpression query = new QueryExpression();
query.Distinct = true;
query.EntityName = "opportunity";
query.ColumnSet = new ColumnSet(true);
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.And;
filter1.AddCondition("statuscode", ConditionOperator.Equal,3);
filter1.AddCondition("statecode", ConditionOperator.Equal, 1);
query.Criteria = filter1;
LinkEntity linkEntity1 = new LinkEntity();
linkEntity1.JoinOperator = JoinOperator.LeftOuter;
linkEntity1.LinkFromEntityName = "opportunity";
LinkEntity1.LinkFromAttributeName = "opportunityid";
linkEntity1.LinkToEntityName = "email";
linkEntity1.LinkToAttributeName = "regardingobjectid";
query.LinkEntities.Add(linkEntity1);
FilterExpression filter2 = new FilterExpression();
The issue is here at this condition. I could use filter on the LinkCriteria but not on the query since it is linked entity.
filter2.AddCondition("regardingobjectid", ConditionOperator.Null);
query.LinkEntities[0].LinkCriteria = filter2;
EntityCollection result = _service.RetrieveMultiple(query);
Console.WriteLine(result.Entities.Count());
Console.ReadKey();
I'm not sure if the query posted is what you are looking for...
If it is, then you should be able to remove filter 2 and add to filter 1
filter1.AddCondition("opportunityid", ConditionOperator.Null);
But comparing the RegardingObjectId to both NULL and the OpportunityID with an AND operation shouldn't ever be true.
I had similar problems adding conditions to linked entities. I found that i could do it using the dynamics 2013 sdk, but you would have to see if you could use the 2013 sdk against a 2011 dynamics. Please see Microsoft Dynamics Crm Sdk - Is this query possible?
The basic difference with the 2013 SDK is you can add a condition to the filter but give it an entity name which is for a linked entity. This means you don't actually add the condition to the link entity itself.
I also show in that link how to use the Linq provider to write the query which is another alternative you may want to try.

Enterprise Keyword not updating in SharePoint 2010

Any idea how to inject values to the Enterprise Keywords column of a List / Doc Lib Item using code?
Tried the following, it didn't give any error, but that column wouldn't update, while the Title did.
using (var site = new SPSite("http://testweb"))
{
using (var web = site.OpenWeb("testsite1"))
{
var list = web.Lists["testlist1"];
var item = list.AddItem();
item["Title"] = string.Format("Injected from code on {0}", DateTime.Now.ToString());
item["Enterprise Keywords"] = "1;#Opera|4eed0518-9676-4afc-be20-9027b3b69e42";
item.Update();
}
}
In this code, Opera keyword has been added previously, I've checked it against the TaxonomyHiddenList list as well using code to extract the correct ID and IdForTerm (the GUID).
What am I missing here?
To add a taxonomy field value the approach is a little bit different. Please try:
TaxonomyField entKeyword = (TaxonomyField)item.Fields["Enterprise Keywords"];
TaxonomyFieldValue term = new TaxonomyFieldValue("1;#Opera|4eed0518-9676-4afc-be20-9027b3b69e42");
entKeyword.SetFieldValue(item,term);
in stead of:
item["Enterprise Keywords"] = "1;#Opera|4eed0518-9676-4afc-be20-9027b3b69e42";

Resources