1

我有表的要求,具有認證:EF查詢

public class Request { 
    public virtual List<Approval> Approvals { get; set; } 
} 

請求來自DB

public DbSet<Request> Request { get; set; } 

我有擴展方法:

public static IQueryable<Request> HaveApprovals(this IQueryable<Request> requests) { 
    return requests.Where(r => r.ActiveApprovals().Count() > 0).ToList(); 
} 

另一種擴展方法:

public static IEnumerable<Approval> ActiveApprovals(this Request request) { 
    return request.Approvals.Where(a => !a.Deleted); 
} 

但得到錯誤:

LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1[Domain.Approval] ActiveApprovals(Domain.Request)' method, and this method cannot be translated into a store expression. 

出於某種原因,一個擴展方法能夠被翻譯成LINQ,但使用內另一分機方法時,則無法翻譯。有什麼建議麼?

+0

你應該從第二個返回IQueryable –

+0

我會如果我可以,但'request.Approvals'是'List',並使用Where返回'IEnumerable'。 – Jaanus

回答

0

嘗試重寫這樣您HaveApprovals擴展:發生

public static IQueryable<Request> HaveApprovals(this IQueryable<Request> requests) { 
    return requests.Where(r => r.Approvals.Any(a => !a.Deleted)).ToList(); 
} 

錯誤,因爲EF試圖在查詢執行服務器端(SQL Server)的任何操作。所以SQL對你的擴展方法以及如何執行它一無所知。

更新#1:

查詢下面

var query = this.DataContext.Products.Where(x => x.Sales.Any(s => s.SectorId == 1)); 

會生成以下SQL查詢

SELECT [t0].[Id], [t0].[Name], [t0].[Description] 
FROM [dbo].[Products] AS [t0] 
WHERE EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[Sales] AS [t1] 
    WHERE ([t1].[SectorId] = @p0) AND ([t1].[ProductId] = [t0].[Id]) 
    ) 
} 

它不會提取所有記錄,這樣就不會降低性能。

+0

我希望它能夠在查詢中執行,否則它會從數據庫加載我的100k條目並且速度很慢。它應該能夠將擴展方法內容轉換爲LINQ,就像它只在使用單個擴展方法時一樣,不是嵌套的。 – Jaanus

+0

我已經用一些證明更新了我的答案。查詢不會提取您的100k項目(請參閱類似的查詢和生成的SQL查詢)。也無法將自定義擴展方法轉換爲SQL。 – akorenchikov

+0

查看本主題以瞭解如果使用IEnumerable,它將執行整個querya並將在內存中完成篩選。 http://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet – Jaanus