Using Linq or Retrieve Multiple
Closed this issue · 7 comments
Is there any way to query multiple results either with a RetrieveMultiple Call or by using Linq?
I've only found .Retrieve by id or alternative key.
Thank you.
Not as of yet. We will look into it and see if we can find a nice solution
Currently the best solution is to use the sets located inside the context generated by XrmContext, for example context.AccountSet. This yields an IQueryable, which can be turned into a list by calling .ToList(), or .Where cases can be added before calling .ToList()
In order to generate a context you specify a name in the "servicecontextname" parameter in the configuration. This yields a custom context as described above, which extends an OrganizationServiceContext, thus you can use it exactly like multiple examples will show you online.
Thank you. That works great.
var opportunities = _XrmServiceContext.OpportunitySet
.Where(x => x.StateCode == 0 && x.CustomerId.Id == account.AccountId.Value && x.CustomerIdType == Account.EntityLogicalName)
.ToList();
Is there a way to restrict the returned column set?
You can use the linq .Select
to select what and how you data should be returned from CRM when you call .ToList()
at the end.
I have extending you example to return the opportunities containing only Id
and CustomerId
:
ar opportunities = _XrmServiceContext.OpportunitySet
.Where(x => x.StateCode == 0 && x.CustomerId.Id == account.AccountId.Value && x.CustomerIdType == Account.EntityLogicalName)
.select(x => new Opportunity(){
OpportunityId = x.OpportunityId,
CustomerId = x.CustomerId
}).ToList();
I tried .Select in a couple of ways but it never worked.
Your solution does. Thank you!
Just a heads up. The context caches records you have previously retrieved from CRM so any new retrieve with the context will only contain fields that was defined in the first select of the first retrieve.
For example:
var opportunities = _XrmServiceContext.OpportunitySet
.Where(x => x.StateCode == 0 && x.CustomerId.Id == account.AccountId.Value && x.CustomerIdType == Account.EntityLogicalName)
.select(x => new Opportunity(){
OpportunityId = x.OpportunityId,
CustomerId = x.CustomerId
}).ToList();
var opportunities2 = _XrmServiceContext.OpportunitySet
.Where(x => x.StateCode == 0 && x.CustomerId.Id == account.AccountId.Value && x.CustomerIdType == Account.EntityLogicalName)
.select(x => new Opportunity(){
OpportunityId = x.OpportunityId,
StateCode = x.StateCode
}).ToList();
Here the returned opportunities in opportunities2
will not contain the data in the 'StateCode' field but will instead contain data in the CustomerId
field due to the caching of previously retrieve records in oppotunities
. A way to clear the cach and ensure you get the data you have specified is to call _XrmServiceContext.ClearChanges()
in between the two calls.
Alternativ, use the using
statment to dispose of the _XrmServiceContext
and encapsulate calls to CRM as so:
using(var _XrmServiceContext = new Xrm(organizationService)){
/// context call here
}
We decided not to implement a RetrieveMultiple extension, since no additional desired funtionality would be added