2012-04-04 15 views
6

Tôi có một lớp truy cập dữ liệu đã mất một lúc để làm việc. Đối với ứng dụng của tôi, tôi cần phải nhận các loại bảng SQL Server khác nhau trong đó mệnh đề WHERE chỉ khác nhau theo tên cột: một số cột là read_time, các cột khác là ReadTime và các cột khác là LastModifiedTime. Vì vậy, tôi nghĩ rằng tôi muốn vượt qua trong mệnh đề WHERE vì vậy tôi không cần phải tạo ra một phương pháp mới cho 50 bảng khác nhau. Nó trông đơn giản, và nó hoạt động, nhưng tôi không hiểu gì cả.Tại sao Func <> và Expression <Func<>> Hoán đổi cho nhau? Tại sao một người làm việc trong trường hợp của tôi?

Phương pháp này, với Expression <> như tham số, hoạt động:

internal List<T> GetObjectsGreaterThanReadTime<T>(Expression<Func<T, bool>> whereClause) where T : class 
{ 
    Table<T> table = this.Database.GetTable<T>(); 
    IEnumerable<T> objects = table.Where(whereClause); 

    return objects.ToList(); 
} 

Bây giờ, tôi đã cố gắng nó theo cách này (dưới đây) trong một thời gian, và nó sẽ chỉ treo trên dòng cuối cùng (ToList()). Đầu tiên, tại sao điều này sẽ biên dịch? Tôi có nghĩa là, tại sao có thể Expression và Func được sử dụng thay thế cho nhau như một tham số? Sau đó, tại sao Expression làm việc, và phiên bản Func chỉ bị treo?

Lưu ý: Sự khác biệt duy nhất giữa phương pháp trên và phương pháp này là tham số phương thức (Biểu thức so với Func).

internal List<T> GetObjectsGreaterThanReadTime<T>(Func<T, bool> whereClause) where T : class 
{ 
    Table<T> table = this.Database.GetTable<T>(); 
    IEnumerable<T> objects = table.Where(whereClause); 

    return objects.ToList(); 
} 
+3

Điều này, cùng với (các) câu trả lời là một phản ứng rất tốt đối với một số "điểm của cây biểu thức là gì?" phong cách của câu hỏi. +1 Q & A –

Trả lời

12

Phiên bản Biểu gọi Queryable.Where mà tạo ra một cây biểu thức, trong đó (khi liệt kê bởi ToList) được phiên dịch sang sql và thực thi trên máy chủ cơ sở dữ liệu. Có lẽ, máy chủ cơ sở dữ liệu sẽ tự tận dụng một chỉ mục dựa trên tiêu chí lọc, để tránh đọc toàn bộ bảng.

phiên bản Các Func gọi Enumerable.Where đó (khi liệt kê bởi ToList) tải toàn bộ bảng (những gì bạn cảm nhận như một hang) và sau đó chạy các tiêu chí lọc chống lại các đối tượng trong bộ nhớ.

+0

Ahhhhhhhhhhhh ... NICE. Làm cho toàn bộ ý nghĩa. Cảm ơn bạn! –