Hi,
Our software developers are starting to use CRM SDK a lot.
As I am reviewing code, I notice that some developers like to write QueryExpressions by constructor and others prefer an object initializer.
By Constructor:
QueryExpression qe = new QueryExpression("account");
qe.ColumnSet = new ColumnSet("accountid", "name");
By Object Initializer:
QueryExpression qe = new QueryExpression()
{
EntityName = "account",
ColumnSet = new ColumnSet("accountid", "name")
};
Advanced By Constructor Query:
private QueryExpression QueryByConstructor()
{
QueryExpression qe = new QueryExpression("contact");
qe.Distinct = true;
qe.ColumnSet = new ColumnSet(_contactColumnSet);
qe.Criteria.Conditions.Add(new ConditionExpression("CFIWCPointsTotal", ConditionOperator.GreaterThan, 0));
qe.Criteria.Conditions.Add(new ConditionExpression("numberofchildren", ConditionOperator.NotNull));
LinkEntity leSystemUser = new LinkEntity();
leSystemUser.EntityAlias = "su";
leSystemUser.Columns = new ColumnSet(_systemUserColumnSet);
leSystemUser.LinkFromEntityName = "contact";
leSystemUser.LinkFromAttributeName = "ownerid";
leSystemUser.LinkToEntityName = "systemuser";
leSystemUser.LinkToAttributeName = "systemuserid";
leSystemUser.JoinOperator = JoinOperator.Inner;
LinkEntity leOpportunity = new LinkEntity();
leOpportunity.EntityAlias = "o";
leOpportunity.Columns = new ColumnSet(_opportunityColumnSet);
leOpportunity.LinkFromEntityName = "new_opportunityterm";
leOpportunity.LinkFromAttributeName = "new_opportunityid";
leOpportunity.LinkToEntityName = "opportunity";
leOpportunity.LinkToAttributeName = "opportunityid";
leOpportunity.JoinOperator = JoinOperator.Inner;
leOpportunity.LinkCriteria.AddCondition(new ConditionExpression("statecode", ConditionOperator.In, new int[] { 0, 1 }));
leOpportunity.LinkCriteria.AddCondition(new ConditionExpression("CFDEquipmentAcceptDate", ConditionOperator.NotNull));
LinkEntity leOpportunityTerm = new LinkEntity();
leOpportunityTerm.EntityAlias = "ot";
leOpportunityTerm.LinkFromEntityName = "new_opportunitytermvendor";
leOpportunityTerm.LinkFromAttributeName = "new_opportunitytermid";
leOpportunityTerm.LinkToEntityName = "new_opportunityterm";
leOpportunityTerm.LinkToAttributeName = "new_opportunitytermid";
leOpportunityTerm.JoinOperator = JoinOperator.Inner;
leOpportunityTerm.LinkCriteria.AddCondition(new ConditionExpression("new_isinlcw", ConditionOperator.Equal, true));
leOpportunity.LinkEntities.Add(leOpportunity);
LinkEntity leOpportunityTermVendor = new LinkEntity();
leOpportunityTermVendor.EntityAlias = "otv";
leOpportunityTermVendor.LinkFromEntityName = "contact";
leOpportunityTermVendor.LinkFromAttributeName = "contactid";
leOpportunityTermVendor.LinkToEntityName = "new_opportunitytermvendor";
leOpportunityTermVendor.LinkToAttributeName = "new_contactid";
leOpportunityTermVendor.JoinOperator = JoinOperator.Inner;
leOpportunityTermVendor.LinkEntities.Add(leOpportunityTerm);
qe.LinkEntities.Add(leSystemUser);
qe.LinkEntities.Add(leOpportunityTermVendor);
return qe;
}
Advanced By Object Initializer Query:
private QueryExpression QueryByObjectInitializer()
{
QueryExpression qe = new QueryExpression()
{
EntityName = "contact",
Distinct = true,
ColumnSet = new ColumnSet(_contactColumnSet),
Criteria =
{
Conditions =
{
new ConditionExpression("CFIWCPointsTotal", ConditionOperator.GreaterThan, 0),
new ConditionExpression("numberofchildren", ConditionOperator.NotNull),
}
},
LinkEntities =
{
new LinkEntity
{
EntityAlias = "su",
Columns = new ColumnSet(_systemUserColumnSet),
LinkFromEntityName = "contact",
LinkFromAttributeName = "ownerid",
LinkToEntityName = "systemuser",
LinkToAttributeName = "systemuserid",
JoinOperator = JoinOperator.Inner,
},
new LinkEntity
{
EntityAlias = "otv",
LinkFromEntityName = "contact",
LinkFromAttributeName = "contactid",
LinkToEntityName = "new_opportunitytermvendor",
LinkToAttributeName = "new_contactid",
JoinOperator = JoinOperator.Inner,
LinkEntities =
{
new LinkEntity
{
EntityAlias = "ot",
LinkFromEntityName = "new_opportunitytermvendor",
LinkFromAttributeName = "new_opportunitytermid",
LinkToEntityName = "new_opportunityterm",
LinkToAttributeName = "new_opportunitytermid",
JoinOperator = JoinOperator.Inner,
LinkCriteria =
{
Conditions =
{
new ConditionExpression("new_isinlcw", ConditionOperator.Equal, true)
}
},
LinkEntities =
{
new LinkEntity
{
EntityAlias = "o",
Columns = new ColumnSet(_opportunityColumnSet),
LinkFromEntityName = "new_opportunityterm",
LinkFromAttributeName = "new_opportunityid",
LinkToEntityName = "opportunity",
LinkToAttributeName = "opportunityid",
JoinOperator = JoinOperator.Inner,
LinkCriteria =
{
Conditions =
{
new ConditionExpression("statecode", ConditionOperator.In, new int[] { 0, 1 }),
new ConditionExpression("CFDEquipmentAcceptDate", ConditionOperator.NotNull)
}
}
}
}
}
}
},
}
};
return qe;
}
Advanced FetchXML Query:
private string FetchXMLQuery()
{
return @"
<fetch version='2017.11.06' top='100' distinct='true' >
<entity name='contact' >
<all-attributes/>
<filter>
<condition attribute='CFIWCPointsTotal' operator='gt' value='0' />
<condition attribute='numberofchildren' operator='not-null' />
</filter>
<link-entity name='systemuser' from='systemuserid' to='ownerid' link-type='inner' alias='su' />
<link-entity name='new_opportunitytermvendor' from='new_contactid' to='contactid' link-type='inner' alias='otv' >
<link-entity name='new_opportunityterm' from='new_opportunitytermid' to='new_opportunitytermid' link-type='inner' alias='ot' >
<filter>
<condition attribute='new_isinlcw' operator='eq' value='1' />
</filter>
<link-entity name='opportunity' from='opportunityid' to='new_opportunityid' link-type='inner' alias='o' >
<filter>
<condition attribute='statecode' operator='in' >
<value>0</value>
<value>1</value>
</condition>
<condition attribute='CFDEquipmentAcceptDate' operator='not-null' />
</filter>
</link-entity>
</link-entity>
</link-entity>
</entity>
</fetch>";
}
I would like for all of our developers to use either one way or another. I am leaning towards the object initializer route since it's easier to read. Imagine if you have 2 or 3 levels of linked entities. It's much easier to read as opposed to the constructor method.
Questions:
- Are there any guidelines for writing QueryExpressions or is it based on preference?
- Which way do you prefer (constructor, object initializer) and why?
Any other tips would be appreciated.