The collection property 'identifierUris' cannot be used in a 'where' query expression - azure-active-directory

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

Related

service.CreateAsync() always returns Id as 0 in ABP

I'm using generated entities from ABP Suite. Sometimes I need Id of inserted entity. But when CreateAsync method is called it returns 0. It internally calls InsertAsync and not InsertAndGetIdAsync. So is there any way to map Id from saved entity?
Here's the code:
[Authorize(BrianPermissions.LabRequirements.Create)]
public virtual async Task<LabRequirementDto> CreateAsync(
LabRequirementCreateDto input)
{
var LabRequirement = await _LabRequirementManager.CreateAsync(
input.TechQualification,
input.TechExperience,
input.Equipments,
input.Others);
UnitOfWorkManager.Current.SaveChangesAsync();
return ObjectMapper.Map<LabRequirement, LabRequirementDto>(LabRequirement);
}
You forget 'await' keyword in your code:
await UnitOfWorkManager.Current.SaveChangesAsync();
Can you try again ?
See: https://docs.abp.io/en/abp/latest/Unit-Of-Work#savechangesasync

How to get the maximum number of members based on users from Azure AD using Graph Api

I am getting the the groups based on users from Microsoft Graph Api. Although I am getting the groups but they are coming to total count of 100.
I tried to use paging technique but it is keep failing. Can someone help me out?
var page = graphClient
.Users[uniqueIdentification]
.MemberOf
.Request()
.GetAsync().Result;
var names = new List<string>();
names.AddRange(page
.OfType<Group>()
.Select(x => x.DisplayName)
.Where(name => !string.IsNullOrEmpty(name)));
The above code only return top 100.
When I tried below code for paging it got cast error .
Error:
Unable to cast object of type 'System.Collections.Generic.List`1[Microsoft.Graph.DirectoryObject]' to type 'System.Collections.Generic.IEnumerable`1[Microsoft.Graph.Group]'.
Code:
var group2 = new List<Group>();
var groupsPage = graphClient.Users[uniqueIdentification].MemberOf.Request().Top(300).GetAsync().Result;
group2.AddRange((IEnumerable<Group>)groupsPage.CurrentPage);
while (groupsPage.NextPageRequest != null)
{
groupsPage = groupsPage.NextPageRequest.GetAsync().Result;
group2.AddRange((IEnumerable<Group>)groupsPage.CurrentPage);
}
The maximum sizes of pages are 100 and 999 user objects respectively
and are default .
Some queries are supported only when you use the
ConsistencyLevel header set to eventual and $count to true
For the error:
Unable to cast object of type 'System.Collections.Generic.List`1[Microsoft.Graph.DirectoryObject]' to type 'System.Collections.Generic.IEnumerable`1[Microsoft.Graph.Group]'.
It looks like here group2 is of type list but trying to add/append the page of type Ienumerable to it which is leading to cast error.(note:list implements Ienumerable (parent) but ienumerable doesn't inherit from list as Ienumerable can be list, queue ,stack )
using System.Linq;
While using var group2 = new List<Group>();
try to add .ToList(); or .Cast<group>().ToList(); depending on latest or old type of versions before adding or appending to the group2 of type list
Please check the References to know further details :
List users - Microsoft Graph v1.0 | Microsoft Docs
How to append enumerable collection to an existing list in C# -
Stack Overflow

How to get the name of a document in a collection after querying in Firestore?

I am programming an app in Flutter and I want to be able to query a set of documents in a collection in Firestore based on specific criteria and then with the documents that fit said criteria get the name of those documents. This is what I have tried so far however it does not work.
getDoc(String topic, int grade) {
return Firestore.instance
.collection('active')
.where(topic, isEqualTo: true)
.where('grade', isEqualTo: grade)
.getDocuments()
.then((docRef) {
return docRef.id;
});
}
All of the code works except for the part where I call docRef.id. When I call docRef.id I get an error saying:
The getter 'id' isn't defined for the class 'QuerySnapshot'.
Try importing the library that defines 'id', correcting the name to the name of an existing getter, or defining a getter or field named 'id'.d
When you perform a query, the result you get in your then callback is a QuerySnapshot. Even if there's only one document matching the conditions, you'll get a QuerySnapshot with a single document in there. To get the individual DocumentSnapshot that are the result, you'll want to loop over the QuerySnapshot.documents.
Something like:
Firestore.instance
.collection('active')
.where(topic, isEqualTo: true)
.where('grade', isEqualTo: grade)
.getDocuments()
.then((querySnapshot) {
querySnapshot.documens.forEach((doc) {
print(doc.documentID)
})
});

How to apply a condition to a specific table in every request on Entity Framework?

I have a many-to-many structure mapped to entity framework. This is a sample of what it looks like:
User UserTag Tag
------- -------- -------
IdUser(PK) IdUserTag(PK) IdTag(PK)
Name IdUser(FK) TagName
Desc IdTag(FK) Active
Now, I needed to exclude from any request of any method the viewing of Tags that were Active=false.
First, I tried doing it manually in every method, like:
public User GetById(int id)
{
var item = UserRepository.GetById(id); //This is just a repository that calls the EF context
//EF automatically maps it to the *UserTags* property
foreach(var tag in item.UserTags)
{
if(tag.Tag.Active == false)
item.UserTags.Remove(tag);
}
}
But it throws the following exception:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable
So, I wanted to know if there's a way to conditionaly filter every request made to a specific table, whether it is select or a join request.
Try this in your GetById method:
var user.UserTags = dbContext.Entry(user)
.Collection(u => u.UserTags)
.Query()
.Where(ut => ut.Active == true)
.ToList();
The supplied code fails because it is attempting to remove items from the data entities not the list. If you want to pass the data entity around instead of the data model, you need to not use Remove. Something like the below (untested should work).
tags = item.UserTags.Where((ut) => ut.Active).ToList();
This line will get you a list of data entities that are active. However, you should really map all of this into a data model (see AutoMapper) and then you would not be removing items from the database.

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

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.

Resources