LINQ to Dynamics CRM Query filtering records locally

前端 未结 3 1525
囚心锁ツ
囚心锁ツ 2021-01-02 01:07

I have written a Linq to CRM query using CRM 2011 RC (v5) LINQ-to-CRM provider. I have a locally declared List which I want to join to a CRM entity and I want the q

相关标签:
3条回答
  • 2021-01-02 01:48

    Edit: Try that one:

    MyObject myObject = new MyObject();
    List<myAccount> myAccountsList = new List<myAccount>();
    
    myAccountsList.Add(new myAccount() {AccountNumber = "123"};
    myAccountsList.Add(new myAccount() {AccountNumber = "456"};
    
    myObject.ListOfAccounts = myAccountsList;
    
    var accountNumbers = myObject.ListOfAccounts.Select(a => a.AccountNumber);
    
    var accountsQuery = orgContext.CreateQuery<customAccountEntity>()
                                  .Where(a => accountNumbers.Contains(a.account_number));
    
    foreach(var item in accountsQuery)
    {
        Console.WriteLine("Id of record retrieved: " + a.Id.ToString());
    }
    

    Edit: if you query provider don't support Contains, build a Where condition with multiple OR, you can use predicate builder to make that easy

    0 讨论(0)
  • 2021-01-02 01:54

    After a lot of head banging and research I have resolved the issue by using Predicate Builder and LINQKit. I need to create an Or based predicate using the keys in my local List<T> then pass the predicate to the Where LINQ extension method. Importantly, I need to call the AsExpandable extension method exposed by LINQKit. So my code would look like this:

    var predicate = PredicateBuilder.False<customAccountEntity>();
    // Loop through the local List creating an Or based predicate
    foreach (var item in myAccountsList)
    {
        string temp = item.AccountNumber;
        predicate = predicate.Or (x => x.customCrmEntityAttribute == temp);
    }
    // The variable predicate is of type Expression<Func<customAccountEntity, bool>>
    var myLinqToCrmQuery =  from ax in myObject.ListOfAccounts
                            from cx in orgContext.CreateQuery<customAccountEntity>().AsExpandable().Where(predicate)
                            where ax.AccountNumber == cx.account_number
                            select cx;
    
    foreach (resultItem in myLinqToCrmQuery)
    {
        Console.WriteLine("Account Id: " + resultItem.Id);
    }
    

    The above code will run a SQL Statement on the CRM Server like this:

    SELECT a.*
    FROM customAccountEntity AS a
    WHERE a.account_number = '123' OR a.account_number = '456'
    

    This means I can create a dynamic where clause at runtime and know that my query will run the filtering logic on the CRM SQL Server. Hope this helps somebody else.

    0 讨论(0)
  • 2021-01-02 01:55

    Instead of playing with predicates you could also simply use the join expression for filtering.

    var myLinqToCrmQuery =  from ax in myObject.ListOfAccounts
                                join cx in orgContext.CreateQuery<customAccountEntity> on ax.AccountNumber equals cx.account_number                      
                                select cx;
    

    Cheers, Lukasz

    0 讨论(0)
提交回复
热议问题