2010-01-11 28 views
8

tôi đã chạy vào vấn đề này:Với LINQ to Entities không hỗ trợ "Phương thức tùy chỉnh", làm thế nào để bạn giữ DRY?

Custom Methods & Extension Methods cannot be translated into a store expression

Về cơ bản tôi có một số LINQ truy vấn phức tạp, vì vậy muốn phá vỡ chúng xuống truy vấn con được thực hiện như phương pháp mà trở IQueryables. Hy vọng của tôi là sau đó các IQueryables có thể được sáng tác với nhau trong một câu lệnh LINQ (như tôi khá chắc chắn bạn có thể làm trong LINQ to SQL).

Vấn đề là nếu bạn cố gắng này, bạn nhận được (ví dụ):

LINQ to Entities không nhận phương pháp 'System.Linq.IQueryable`1 [Chủ đề] GetThreadsByMostReccentlyPosted (Int32) Phương thức ' và phương pháp này không thể là được dịch sang biểu thức cửa hàng.

Có vẻ như khá cơ bản đối với tôi rằng nếu bạn sử dụng LINQ ORM thì bạn cần có khả năng soạn các truy vấn LINQ. Nếu không, bất kỳ logic truy vấn thông thường nào cũng phải được sao chép & được dán.

Với giới hạn này, làm thế nào tôi có thể ở lại DRY với LINQ to Entities?

+0

vì vậy những gì bạn thực sự muốn biết là "Làm thế nào để thực hiện chậm trễ trong EF, như tôi có thể trong L2S?". –

+0

cách duy nhất tôi có thể thấy để làm điều này cho đến nay là chuyển đổi IQueryable của tôi thành một IEnumerable, tại thời điểm đó tôi nghi ngờ bạn mất khả năng cho một câu lệnh SQL tối ưu được tạo ra – Schneider

+0

Không - không liên quan gì đến việc thực thi bị trì hoãn. Về cơ bản nó sẽ không cho phép tôi viết các câu lệnh linq bao gồm các phương thức – Schneider

Trả lời

12

Hai cách:

  1. Phương pháp mà trở lại biểu thức có thể được sử dụng
  2. riêng các queryable và bit đếm

Đối # 1, hãy xem xét:

public Expression<Func<Foo, bool>> WhereCreatorIsAdministrator() 
{ 
    return f => f.Creator.UserName.Equals("Administrator", StringComparison.OrdinalIgnoreCase); 
} 

public void DoStuff() 
{ 
    var exp = WhereCreatorIsAdministrator(); 
    using (var c = new MyEntities()) 
    { 
     var q = c.Foos.Where(exp); // supported in L2E 
     // do stuff 
    } 
} 

Đối với một ví dụ về số 2, hãy đọc bài viết này: How to compose L2O and L2E queries. Hãy xem xét ví dụ được cung cấp ở đó:

var partialFilter = from p in ctx.People 
        where p.Address.City == “Sammamish” 
        select p; 

var possibleBuyers = from p in partiallyFilter.AsEnumerable() 
        where InMarketForAHouse(p); 
        select p; 

Điều này có thể kém hiệu quả hơn hoặc có thể không sao. Nó phụ thuộc vào những gì bạn đang làm. Nó thường là tốt cho chiếu, thường không OK cho các hạn chế.

Cập nhật Chỉ cần xem an even better explanation of option #1 từ Damien Guard.

+0

Tôi thích tùy chọn một. [Tôi đã viết một blog về chủ đề này] (http://www.codetunnel.com/blog/post/64/how-to-simplify-complex-linq-expressions) bởi vì tôi đã có một số biểu thức LINQ phức tạp điên rồ mà nhận được khó duy trì. Vài việc đã được hoàn thành. – Chev

0

EF không thể soạn truy vấn từ biểu thức LINQ bao gồm một phương thức. EF cần các giá trị theo nghĩa đen để soạn SQL. Bạn sẽ phải thực hiện với các truy vấn "phổ biến" trả về một superset của các thực thể bạn cần cho một trường hợp cụ thể, sau đó sử dụng các phương thức mở rộng và LINQ để thu hẹp bộ trả lại khi nó đã được trả về từ cơ sở dữ liệu. Quay lại đầu trang

+0

bạn có nghĩa là IEnumerables khi bạn nói "Common queries"? ví dụ. một cái gì đó có một kết quả đặt như trái ngược với một IQueryable? – Schneider

+0

Bằng "truy vấn phổ biến", tôi có nghĩa là các truy vấn được tham số hóa có thể được sử dụng để trả về các siêu dữ liệu có kích thước quản lý của các thực thể bạn muốn. Các truy vấn bạn thiết kế sẽ tùy thuộc vào dữ liệu của bạn và số tiền bạn có. –

+0

Tôi hiểu. Nhưng điều này ngụ ý trong bộ nhớ tham gia vv? – Schneider

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