2011-02-09 33 views
12

Tôi đã viết truy vấn LINQ to CRM bằng cách sử dụng nhà cung cấp CRM 2011 RC (v5) LINQ-to-CRM. Tôi có một danh sách được khai báo cục bộ <T> mà tôi muốn tham gia vào một thực thể CRM và tôi muốn truy vấn được thực hiện trên Máy chủ CRM. Ví dụ có thể giúp:LINQ to Dynamics CRM Hồ sơ lọc truy vấn cục bộ

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

Mã trên biên dịch và thực thi, tuy nhiên, việc lọc các bản ghi được thực hiện cục bộ sau khi truy xuất toàn bộ bản ghi thực thể CRM. Rõ ràng khi thực thể CRM chứa hàng nghìn hàng, truy vấn sẽ hoạt động kém hoặc thậm chí hết thời gian chờ.

Tôi đã đọc về IQueryable và IEnumerable và đã thử chuyển đổi Danh sách bằng phương thức mở rộng AsQueryable(), không có hiệu lực. Tôi cần truy vấn LINQ trên của tôi để chạy SQL như sau:

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

Hoặc sử dụng bảng tạm thời nếu muốn tham gia nhiều trường. Làm thế nào tôi có thể thực hiện điều này?

Trả lời

12

Sau rất nhiều đầu đập và nghiên cứu tôi đã giải quyết vấn đề bằng cách sử dụng Predicate BuilderLINQKit. Tôi cần phải tạo một vị từ dựa trên Hoặc bằng cách sử dụng các phím trong Danh sách cục bộ của tôi < T> rồi chuyển vị từ này sang phương thức mở rộng Where LINQ. Quan trọng hơn, tôi cần gọi phương thức mở rộng AsExpandable được LINQKit hiển thị. Vì vậy, mã của tôi sẽ trông như thế này:

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

Đoạn mã trên sẽ chạy một câu lệnh SQL trên máy chủ CRM như thế này:

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

này có nghĩa là tôi có thể tạo ra một động lực mệnh đề where trong thời gian chạy và biết truy vấn của tôi sẽ chạy logic lọc trên Máy chủ SQL CRM. Hy vọng điều này sẽ giúp người khác.

0

Chỉnh sửa: Cố gắng mà một:

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: nếu bạn truy vấn cung cấp dịch vụ không hỗ trợ Có, xây dựng một tình trạng ở đâu với nhiều OR, bạn có thể sử dụng predicate builder để làm điều đó dễ dàng

+0

Tôi đã sử dụng các nhà cung cấp truy vấn LINQ-to-CRM - Tôi có thể sử dụng nhiều hơn một nhà cung cấp trong cùng một truy vấn? – Iftekhar

+0

Ok sau khi xem xét kỹ truy vấn của bạn, tôi nghĩ bạn nên làm theo cách khác (không tham gia nhưng chứa) – Guillaume86

+0

Tôi muốn truy vấn của mình được dịch sang SQL và lọc để chạy trên Máy chủ SQL. Phương thức Contains extension chỉ đơn giản là lọc nội bộ. – Iftekhar

1

Thay vì chơi với các vị từ, bạn cũng có thể chỉ cần sử dụng biểu thức nối để lọc.

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

Chúc mừng, Lukasz

+1

Tôi muốn truy vấn chạy trên máy chủ. Với biểu thức nối, việc lọc được thực hiện cục bộ trên máy khách. – Iftekhar

Các vấn đề liên quan