Dynamically Construct Linq in CRM 2011

落爺英雄遲暮 提交于 2019-12-23 02:17:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!