Vì IQueryable không nhận delegate mà nhận expression tree — cây mô tả lời gọi để provider dịch sang SQL.
Method C# của bạn chỉ là IL đã biên dịch, provider không có cách nào chuyển thành mệnh đề WHERE, nên EF Core ném:
The LINQ expression '...' could not be translated.Từ EF Core 3.0, đây là hành vi cố ý. Trước đó EF âm thầm chuyển sang client evaluation: kéo toàn bộ bảng về bộ nhớ rồi lọc bằng C# — chạy được lúc dev với 100 dòng, sập lúc production với vài triệu dòng. EF Core 3.0 chỉ còn cho phép client evaluation ở projection ngoài cùng (lần Select cuối), mọi chỗ khác dịch không được là ném lỗi.
Ba hướng xử lý, theo thứ tự ưu tiên:
1. Viết lại bằng biểu thức dịch được: Where(o => o.IsPaid && o.Total > 0).
2. Tách thành Expression<Func<T, bool>> dùng lại được — đây mới là cách chuẩn để tái sử dụng điều kiện:
public static Expression<Func<Order, bool>> IsValid =>
o => o.IsPaid && o.Total > 0;
var rows = await db.Orders.Where(Order.IsValid).ToListAsync(ct);3. Chuyển sang client có chủ đích bằng AsEnumerable() — nhưng phải đặt sau các bộ lọc chính, và biết rõ mình đang kéo bao nhiêu dòng về.
Cùng nguyên nhân này giải thích vì sao method như ToString() tuỳ biến hay property [NotMapped] cũng không dùng được trong Where.