Tôi đã dành 6 tháng qua để chiến đấu với hạn chế này với EF 3.5 và mặc dù tôi không phải là người thông minh nhất trên thế giới, nhưng tôi khá chắc rằng mình có điều gì đó hữu ích để cung cấp về chủ đề này.
SQL được tạo ra bằng cách trồng một cây biểu thức "kiểu HOẶC" cao 50 dặm sẽ dẫn đến một kế hoạch thực thi truy vấn kém. Tôi đang xử lý một vài triệu hàng và tác động là đáng kể.
Có một thủ thuật nhỏ mà tôi tìm thấy để thực hiện một SQL 'in' giúp ích nếu bạn chỉ đang tìm kiếm một loạt các thực thể theo id:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
trong đó pkIDColumn là tên cột id khóa chính của bảng Entity1 của bạn.
NHƯNG HÃY TIẾP TỤC ĐỌC!
Điều này là tốt, nhưng nó yêu cầu rằng tôi đã có id của những gì tôi cần tìm. Đôi khi tôi chỉ muốn các biểu hiện của mình tiếp cận với các mối quan hệ khác và những gì tôi có là tiêu chí cho những mối quan hệ được kết nối đó.
Nếu có nhiều thời gian hơn, tôi sẽ cố gắng biểu diễn điều này một cách trực quan, nhưng tôi không nên chỉ nghiên cứu câu này một chút: Hãy xem xét một lược đồ với các bảng Person, GovernmentId và GovernmentIdType. Andrew Tappert (Person) có hai thẻ id (GovernmentId), một từ Oregon (GovernmentIdType) và một từ Washington (GovernmentIdType).
Bây giờ tạo một edmx từ nó.
Bây giờ, hãy tưởng tượng bạn muốn tìm tất cả những người có một giá trị ID nhất định, giả sử 1234567.
Điều này có thể được thực hiện với một lần truy cập cơ sở dữ liệu duy nhất với điều này:
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
Bạn có thấy truy vấn con ở đây không? Sql được tạo sẽ sử dụng 'nối' thay vì truy vấn phụ, nhưng hiệu quả là như nhau. Ngày nay, máy chủ SQL vẫn tối ưu hóa các truy vấn con thành các phép nối bên dưới, nhưng dù sao ...
Chìa khóa để làm việc này là .Any bên trong biểu thức.