问题
I am trying to retrieve all records of an entity with Linq with the condition that one of the properties that are true in the parameter are true in the record.
I am trying to achieve a logical 'or', please look at the code as it will make more sense there.
In FetchXML it is working:
public void GetLock(bool account = false, bool contact = false, bool incident = false)
{
var fetch = @"
<fetch mapping='logical'>
<entity name='de_processimport'>
<attribute name='de_processimportid' />
<filter type='or'>";
if (account)
fetch += @"<condition attribute='de_processingaccount' operator='eq' value='true' />";
if (contact)
fetch += @"<condition attribute='de_processingcontact' operator='eq' value='true' />";
if (incident)
fetch += @"<condition attribute='de_processingincident' operator='eq' value='true' />";
fetch += @"
</filter>
</entity>
</fetch>";
var processing = service.RetrieveMultiple(new FetchExpression(fetch));
...
}
In Linq it is not working:
public void GetLock(bool account = false, bool contact = false, bool incident = false)
{
var processing = linq.de_processimportSet
.Where(p => // get records that are processing the entities we are processing
(account) ? p.de_ProcessingAccount == true : false // get processImport records where processingAccount is true or otherwise ignore this clause (false)
|| (contact) ? p.de_ProcessingContact == true : false
|| (incident) ? p.de_ProcessingIncident == true : false
);
...
}
回答1:
CRM reads the created Linq statement and is very particular. This should work for you since the set is of type IQueryable, you can add your where statements as needed:
public void GetLock(bool account = false, bool contact = false, bool incident = false)
{
var query = linq.de_processimportSet;
if(account){
query = query.Where(p => p.de_ProcessingAccount);
}
if(contact){
query = query.Where(p => p.de_ProcessingContact);
}
if(incident){
query = query.Where(p => p.de_ProcessingIncident);
}
var processing = query.ToList();
}
Edit
CRM's Linq doesn't support this out of the box, but you can download LinqKit and use it's predicate builder and AsExpandable magic to make it work. Check out a similar example here
You could also abandon Linq and use Query Expressions in this case:
public void GetLock(bool account = false, bool contact = false, bool incident = false)
{
var qe = new QueryExpression("de_processimport");
qe.ColumnSet = new ColumnSet(true);
if(account){
qe.AddCondition("de_processingaccount" ConditionOperator.Equal, true);
}
if(contact){
qe.AddCondition("de_processingcontact" ConditionOperator.Equal, true);
}
if(incident){
qe.AddCondition("de_processingincident" ConditionOperator.Equal, true);
}
var processing = service.RetrieveMultiple(qe).Entities.Select(c => c.ToEntity<de_processimport>());
}
来源:https://stackoverflow.com/questions/18636095/dynamically-construct-linq-in-crm-2011