這是我的自定義過濾器(Func),用于在where子句中傳遞
。Func<Project,bool> filter = f =>
{
bool filteredContent = true;
if (! CreatorId.Equals(0)
filteredContent = f.CreatedBy.Equals(CreatorId)。
if (filteredContent && !VerticalMarketId.Equals(0)
filteredContent = f.VerticalMarketsId.Equals(VerticalMarketId)。
if (filteredContent && !ProductCategoryId.Equals(0)
filteredContent = f.ProductCategoriesId.Equals(ProductCategoryId)。
return filteredContent;
};
這是我的代碼,我根據過濾器運算式中創建的條件獲得所有的專案
。 getProjects = await _context.Projects.Where(x => x. IsDeleted == false && filter.Invoke(x))// Here I'm getting the exception.
.Include(PC => PC.ProjectComments.Where(x => x.IsDeleted == false)
.Include(SP => SP.SharedProjects)
.AsNoTracking().ToListAsync()。
例外:LINQ運算式(DbSet......)無法被翻譯。 翻譯。要么以可以被翻譯的形式重寫查詢。 或者通過插入一個對 AsEnumerable"、"AsAsyncEnumerable"、"ToList "或 "ToListAsync"。
誰能告訴我如何在此使用運算式過濾資料?
注意:我可以在應用過濾器之前執行ToListAsync(),但是它將從DB中獲取所有記錄,然后在客戶端進行過濾。但是我想在服務器端過濾資料。
uj5u.com熱心網友回復:
如果你使用的是Linq To Objects,這應該是可行的,但你正在做的是Linq To SQL,在這種情況下,你必須考慮如何將這個函式轉換為一個有效的SQL陳述句。問問你自己。我怎樣才能在SQL陳述句中傳遞這個函式呼叫?根據你在運算式主體上所做的作業,你不能把它翻譯成SQL,你有時必須更簡單一些。
候選者
候選解決方案 添加
在你的專案中添加PredicateBuilder類。它將為你提供輕松的邏輯運算子,讓你處理運算式。
嘗試定義一個運算式并將其作為引數傳遞給你的查詢方法鏈的Where方法。示例(請閱讀評論):
//定義一個帶有默認條件的運算式。
Expression<Func<Project, bool>> filter = f => !f.IsDeleted;
//檢查條件,用`And`邏輯運算子添加新的檔案。
if (! CreatorId.Equals(0)
filter = filter.And(f => f.CreatedBy.Equals(CreatorId))。
else if (! VerticalMarketId.Equals(0)
filter = filter.And(f => f.VerticalMarketsId.Equals(VerticalMarketId))。
else if (! ProductCategoryId.Equals(0)
filter = filter.And(f => f.ProductCategoriesId.Equals(ProductCategoryId))。
//在查詢中應用過濾器并執行它。
getProjects = await _context.Projects.Where(filter)
.Include(PC => PC.ProjectComments.Where(x => !x.IsDeleted))
.Include(SP => SP.SharedProjects)
.AsNoTracking()
.ToListAsync()。
注意:我沒有測驗這段代碼,它可能應該以某種方式被修復!
重要提示
Linq To SQL的重要提示:
- 邏輯運算子是可以的,而且往往可以很好地翻譯成sql;
Where(x => x.Children.Any(j => j.Children.Any()),每個Any呼叫都會在查詢范圍內生成一個子查詢,鑒于它可能影響你的資料庫性能,請小心使用它。- 如果你只需要檢查一個專案的存在,使用
queryable.Any(expression)。 - 如果你需要檢查,然后做一些事情,最好使用
queryable.FirstOrDefault(expression)并在使用前檢查結果是否為空。 - 使用
.Take(int)和.Skip(int)進行分頁。 - 總是通過呼叫
.ToList()、.ToArray()或這些方法的異步版本來具體化你的查詢。避免在頂層傳遞queryable(查詢可以在你想要的范圍外執行)。
uj5u.com熱心網友回復:
我通過創建一個簡單的運算式想出了這個問題,如下所示:
private static Expression<Func<Project, bool> > ProjectFilterExpression(
int creatorId,
int verticalMarketId,
int productCategoryId)
{
Expression<Func<Project, bool>> projectFilterExpression = pfe =>
!pfe.IsDeleted
//CreatorId過濾器
&& (creatorId.Equals(0) || pfe.CreatedBy.Equals(creatorId) )
//Vertical Market Filter。
&& (verticalMarketId.Equals(0) || pfe.VerticalMarketsId.Equals(verticalMarketId) )
//產品類別過濾器
&& (productCategoryId.Equals(0) || pfe.ProductCategoriesId.Equals(productCategoryId)) 。
return projectFilterExpression;
然后我在我的過濾器方法中呼叫這個靜態方法。
var filter = ProjectFilterExpression(CreatorId, VerticalMarketId, ProductCategoryId)。
最后我在我的LINQ where子句中應用了這個過濾器
getProjects = await _context.Projects.Where(filter).AsNoTracking().ToListAsync()。
它的作業完全正常。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/327606.html
標籤:
