簡體   English   中英

LINQ to Dynamics CRM查詢本地過濾記錄

[英]LINQ to Dynamics CRM Query filtering records locally

我使用CRM 2011 RC(v5)LINQ-to-CRM提供程序編寫了一個Linq to CRM查詢。 我有一個本地聲明的List <T>,我想加入CRM實體,我希望查詢在CRM服務器上執行。 一個例子可能有幫助:

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 accountsQuery = from ax in myObject.ListOfAccounts
                    join a in orgContext.CreateQuery<customAccountEntity>() on ax.AccountNumber equals a.account_number
                    select a;

foreach(var item in accountsQuery)
{
    Console.WriteLine("Id of record retrieved: " + a.Id.ToString());
}

上面的代碼編譯並執行,但是,在檢索整個CRM實體記錄集之后,本地執行記錄的過濾。 顯然,當CRM實體包含數千行時,查詢將執行不佳甚至超時。

我已閱讀有關IQueryable和IEnumerable的內容,並嘗試使用AsQueryable()擴展方法轉換List,該方法無效。 我需要上面的Linq查詢來運行SQL,如下所示:

SELECT a.*
FROM customAccountEntity AS a
WHERE a.account_number IN ('123', '456');

如果想要加入多個字段,可以使用臨時表。 我怎么能做到這一點?

經過大量的敲擊和研究后,我通過使用Predicate BuilderLINQKit解決了這個問題。 我需要使用本地List <T>中的創建一個基於Or的謂詞,然后將謂詞傳遞給Where LINQ擴展方法。 重要的是,我需要調用LINQKit公開的AsExpandable擴展方法。 所以我的代碼看起來像這樣:

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);
}

上面的代碼將在CRM服務器上運行SQL語句,如下所示:

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

這意味着我可以在運行時創建一個動態where子句,並知道我的查詢將在CRM SQL Server上運行過濾邏輯。 希望這有助於其他人。

您可以簡單地使用連接表達式進行過濾,而不是使用謂詞。

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

干杯,盧卡斯

編輯:嘗試那個:

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());
}

編輯:如果查詢提供程序不支持Contains,使用多個OR構建Where條件,則可以使用謂詞構建器使其變得容易

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM