I have written a Linq to CRM query using CRM 2011 RC (v5) LINQ-to-CRM provider. I have a locally declared List
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
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.
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