2009-04-27 25 views
15

Tôi có một phương pháp 'không dịch sang SQL' mà tôi muốn thực hiện trên IQueryable, có cách nào để buộc IQueryable thực thi mà không cần lưu trữ nó trong một số lớp trung gian không?Buộc một IQueryable để thực thi?

+0

Đây là một chẩn đoán mù nhưng nếu string.IsNullOrEmpty là thủ phạm sau đó sử dụng 2 nơi mệnh đề thay thế: .Where (o => o.Name! = Null) .Where (o => o.Name.Length> 0) . – mayu

Trả lời

25

Có phải vấn đề mà bạn muốn phương pháp thực thi cục bộ thay vì trong cơ sở dữ liệu không? Nếu vậy, AsEnumerable là bạn của bạn. Đó là một phương pháp rất đơn giản, một cái gì đó như:

public IEnumerable<T> AsEnumerable(IEnumerable<T> source) 
{ 
    return source; 
} 

Điều quan trọng là nó làm cho các loại thời gian biên dịch của kết quả IEnumerable<T> hơn IQueryable<T>, có nghĩa là bất kỳ nhà khai thác truy vấn LINQ bạn gọi sau đó sẽ là LINQ với các đối tượng thay vì LINQ to SQL.

Ví dụ:

var query = context.Employees 
        // Filtering performed in SQL 
        .Where(emp => emp.IsFullTime) 
        .AsEnumerable() 
        // Projection performed locally; ComputeSalary has no 
        // SQL equivalent 
        .Select(emp => new { Employee = emp, 
             Salary = ComputeSalary(emp) }); 

Bạn có thể gọi ToList như đề xuất ở nơi khác, nhưng nếu bạn đang thực hiện lọc và không thực sự cần danh sách đầy đủ trong bộ nhớ, gọi AsEnumerable và lọc rằng kết quả sẽ hiệu quả hơn tải mọi thứ trước tiên.

+1

Liệu kỹ thuật này với LINQ to EF là tốt? Nó không có vẻ như vậy. – neontapir

+0

Tôi không hiểu những gì 'thực thi cục bộ hơn là trong cơ sở dữ liệu'. Đối với những người như tôi: IQueryable as = from a in x select a; sau đó a.Count(); a.Foreach (...) sẽ thực thi hai truy vấn SQL. – mayu

+2

@Tymek: Có, thực thi hai truy vấn SQL. Nhưng bằng cách "thực hiện cục bộ", tôi có nghĩa là "lấy tất cả các kết quả trong truy vấn từ cơ sở dữ liệu, nhưng sau đó thực hiện phần còn lại của truy vấn trong bộ nhớ" - vì vậy bạn có thể thực hiện lọc, dự vv mà không thể áp dụng trong SQL. –

6
List<Employees> myEmployees = myqueryable.ToList(); 

và sau đó bạn có thể thực hiện công cụ LINQ của mình trên Danh sách đó.

2

Bạn nhận được thông báo đó khi bạn đã viết một truy vấn mà LinqToSql không biết làm thế nào để dịch sang SQL (đó là những gì nó nói quá).

Tôi không chắc chắn tôi nhận được chính xác những gì bạn đang yêu cầu, nhưng như xa như tôi thấy, bạn có các tùy chọn sau:

  1. Viết lại câu hỏi của bạn để LinqToSql THỂ dịch nó
  2. Hãy làm như phần lớn các truy vấn như bạn có thể trên Sql server, sau đó làm phần còn lại trong bộ nhớ (sử dụng LINQ to Objects)
  3. Sit xuống và khóc

Giả sử chúng ta loại trừ # 3, chúng ta hãy nhìn vào những khác 2 ví dụ.

  1. Viết lại - để trợ giúp điều đó, chúng tôi cần truy vấn LINQ của bạn.

  2. Tại đây bạn lấy phần không thể dịch được từ truy vấn ban đầu, sau đó trên ToList gọi hàm Iqueryable và sau đó áp dụng phần còn lại của truy vấn trên danh sách đó.

Và bạn có thể thực hiện truy vấn mà không phải lưu trữ truy vấn không? Vâng, không thực sự, bạn luôn có thể lặp qua các kết quả và như vậy không lưu trữ nó trong một biến, nhưng rõ ràng là kết quả của truy vấn cần được lưu trữ ở đâu đó.

+1

Người ta không cần ngồi xuống khóc. – mayu

+2

Rất đúng - tuy nhiên tôi cảm thấy không có người nào phải khóc khi đứng. Nếu bạn phải khóc, bạn cần phải làm điều đó đúng cách. – kastermester

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