How to perform an 'OR' query with S4S connector? - salesforce

I'm trying figure out how to query Salesforce with multiple filters where either filter can be true (similar to a traditional WHERE x='' OR y='' SQL statement).
The following appears works, but produces an 'AND' query where both filters must be true:
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
dataSource.AddDataSourceFilter("Contact__c", new Operator(ComparisonOperator.Equals), profile.ContactId);
dataSource.AddDataSourceFilter("Lead__c", new Operator(ComparisonOperator.Equals), profile.LeadId);
var downloads = dataSource.GetQueryResultsAsEntities();
I would like to avoid hard-coding SOQL queries into my .NET application, if possible. Does the S4S API support these sorts of queries, or should I be using SOQL for this?

The Sitecore for Salesforce Connector (S4S) has composite filters that allow you to programmatically create a DataSource that is converted into a SOQL query with OR operators in the where clause.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
var orFilter = new LogicalDisjunctionFilter();
orFilter.AddDataSourceFilter("Contact__c", ComparisonOperator.Equals, profile.ContactId);
orFilter.AddDataSourceFilter(ApexLog.Fields.Location, ComparisonOperator.Equals, "SystemLog");
// The two filters above will be combined with a logical OR
dataSource.AddDataSourceFilter(orFilter);
var downloads = dataSource.GetQueryResultsAsEntities();
You can use combinations of the LogicalDisjunctionFilter with the LogicalConjunctionFilter to build up AND and OR logic as required.
Alternatively, you could directly add the SOQL where clause to the datasource.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
dataSource.SoqlFilter = string.Format("Contact__c = '{0}' OR Location = 'SystemLog'", profile.ContactId);
var downloads = dataSource.GetQueryResultsAsEntities();
Or, as Matt suggests, you could build up your own SOQL string and run that directly.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
var queryResult = dataSource.RunSoqlQuery(new SoqlQuery(string.Format("Select Id from Download__c where Contact__c = '{0}' OR Location = 'SystemLog'", profile.ContactId)));
var downloads = dataSource.EntitysFromQueryResult<GenericSalesforceEntity>(queryResult);

SOQL would make this much easier so that should be the route you choose if available to you, especially since it offers the easiest way to perform logical operations with your filters.

Related

SuiteScript 2.0: How do you load a dataset and then add conditions?

The situation:
I am trying to load a dataset and then add additional criteria (filters) to the dataset based off users selected fields. The whole dev is a "Custom Report" build using a suitlete that has some fields the user can populate to choose "dynamic filters". When they click on the generate button I add the criteria/filters to a search and dataset and then join the results and display them.
The issue is that while I am able to add filters to the search after I load it no matter what I try I can't seem to add filters to the Dataset.
This code gets the dataset Data:
var datasetData = datasetLib.load({ id: datasetId });
resultSet.pageRanges.forEach(function (pageRange) {
// Fetch the results on the current page
var myPage = resultSet.fetch({ index: pageRange.index });
res.data = res.data.concat(myPage.data.results);
if (res.columns.length < 1) {
var columns = JSON.parse(myPage.pagedData.queryDefinition).columns;
for (var i = 0; i < columns.length; i++) {
res.columns.push(columns[i].label);
}
}
});
I attempted many different iterations to create the condition... here is one:
dataset.createCondition({
column: datasetData.columns[0], // I loaded the dataset and use it to reference the column
operator: query.Operator.ANY_OF,
values: params.customer.split(',')
})
Now the above code DOSE create a condition but when I attempt to add it into the dataset's current conditions I receive errors.I am attempting to push it into the child parameter of the parent criteria.
Please ask if you need more info...
If using a workbook is fine then I would suggest you to load the workbook using your above dataset using the query module and then use the above createCondition to add the condition to the loaded query dynamically.
var myLoadedQuery = query.load({
id: 'custworkbook237'
});
var mySalesRepJoin = myLoadedQuery.autoJoin({
fieldId: 'salesrep'
});
var thirdCondition = mySalesRepJoin.createCondition({
fieldId: 'email,
operator: query.Operator.START_WITH_NOT,
values: 'foo'
});
I would also urge to ensure the joins are accurately represented by looking at the Records catalog via Setup>Records Catalog. Hope this helps.

DotNet Core Azure Search SDK - filtering results

We are trying to implement Filter functionality into Azure (Cognitive) Search. I was hoping to find some nice SDK methods that hide all the ugly parts, but so far the only example I found looks like this (source):
SearchParameters parameters = new SearchParameters()
{
Filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", groups.Select(g => g.ToString()))),
Select = new[] { "application essays" }
};
I was wondering, whether I am missing some docs. Or maybe it is on the roadmap?
Check out our new Azure.Search.Documents SDK we released last month. It does have OData filter helps as you can find here:
int stars = 4;
SearchOptions options = new SearchOptions
{
// Filter to only Rating greater than or equal our preference
Filter = SearchFilter.Create($"Rating ge {stars}"),
Size = 5, // Take only 5 results
OrderBy = { "Rating desc" } // Sort by Rating from high to low
};
It'll escape string parameters correctly. The OData $filter syntax still requires raw input, but the type helpers in the formattable string should make your situation easier: you don't have to worry about escaping values yourself.

How to sort when also using a where clause

I am currently pulling a list from a database, using the following code. The list is retrieved using a WHERE condition, however the list is returned unsorted. This is in the controller.
How can I modify this code so that the returned list is sorted alphabetically?
if (!string.IsNullOrEmpty(TargetYear))
{
ViewBag.HSID = new SelectList(db.Hotspots.Where(g => g.HSID.Contains(TargetYear)).ToList(), "ID", "HSID");
}
On several other fields I have used the following method to order, but I'm not sure how, or if I can combine this with the where clause above. The key piece is ".OrderBy(e=>e.FIELD), however this is precisely the piece I'm not sure how to integrate with the query.
ViewBag.LocalityCode = new SelectList(db.Localities.OrderBy(e=>e.LOCALITY1), "LOC_CODE", "LOCALITY1");
Other helpful bits of info:
ASP.Net MVC5
Microsoft SQL 2012
if (!string.IsNullOrEmpty(TargetYear))
{
var data =
db.Hotspots
.Where(g => g.HSID.Contains(TargetYear))
.OrderBy(e=>e.HSID)
.ToList();
ViewBag.HSID = new SelectList(data,"ID", "HSID");
}

IDistributedCache Removing keys

I've recently started using the sql version of IDistributedCache on a dotnet core web api.
How would you remove/invalidate a set of keys for say a specific user?
I.e: I structured the keys to follow this convention:
/users/{userId}/Key1
/users/{userId}/Key2
/users/{userId}/Section/Key3
I cannot find any method to remove all keys starting with: /users/{userId}
How do you remove more than one item from the IDistributedCache at a time?
Removing via SQL statement is not a good solution because the webapp process performs some kind of lock. For example, I had to manually stop after three minutes and half the following simple query Delete from SqlSession with only two records.
So I ended up this way: I retrieve data with a simple query like
Select Id from SqlSession where Id like 'MyIdGroup%'
or with Entity framework
var cacheElementsToDelete = await _dbContext.SQLSessions
.Where(a => a.Id.StartsWith("MyIdGroup"))
.ToListAsync();
Then I use the method of the IDistributedCache to remove each item
foreach (var item in cacheElementsToDelete)
{
await _cache.RemoveAsync(item.Id);
}

The collection property 'identifierUris' cannot be used in a 'where' query expression

Using Microsoft.Azure.ActiveDirectory.GraphClient.ActiveDirectoryClient api I am trying to find an existing Application in AAD which has the same as my desired IdentifierUrl. This is so i can decide on creating one or leaving the existing one alone.
I'm using the following calls. However I get this error:
The collection property 'identifierUris' cannot be used in a 'where' query expression. Collection properties are only supported as the source of 'any' or 'all' methods in a 'where' query option
What is the recommended way of doing this? thanks
public static async Task<IApplication> FindApplicationByUrlAsync(string accessToken, string tenantId, string identifierUrl)
{
var graphClient = NewActiveDirectoryClient(accessToken, tenantId);
var matches = await graphClient.Applications.Where(app => app.IdentifierUris.Contains(identifierUrl)).ExecuteAsync();
return matches.CurrentPage.ToList().FirstOrDefault();
}
Use the Any function:
var result = await client.Applications.Where(a => a.IdentifierUris.Any(i => i == identifierUri)).ExecuteAsync();
That'll get translated into a request as follows:
https://graph.microsoft.com/beta/applications?$filter=identifierUris/any(c:c eq 'yourIdentifierUri')
More info on filters for the Azure AD Graph here:
https://msdn.microsoft.com/en-us/library/azure/ad/graph/howto/azure-ad-graph-api-supported-queries-filters-and-paging-options

Resources