2012-09-05 37 views
5

Điều này đã khiến tôi không có vấn đề gì ngày hôm nay. Tôi có câu hỏi này đơn giảnKhuôn khổ thực thể: Không thể tạo giá trị không đổi của loại 'System.Collections.Generic.IList`1'

var result = 
    DataContext.Accommodations.Where(a => 
     (criteria.MinPrice == null || a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) && 
     (criteria.MaxPrice == null || a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice)) && 
     (criteria.Locations == null || criteria.Locations.Count == 0 || a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName))) 
); 

Dòng cuối cùng của truy vấn này đang gây ra cho tôi vấn đề

(criteria.Locations == null || 
criteria.Locations.Count == 0 || 
a.AccommodationPlaceJoins.Any(j => criteria.Locations.Contains(j.Place.PlaceName))) 

Các lỗi nó mang lại là

Không thể để tạo ra một giá trị không đổi kiểu ' System.Collections.Generic.IList`1 '. Chỉ các kiểu nguyên thủy ('chẳng hạn như Int32, String và Guid') được hỗ trợ trong ngữ cảnh này.

Tôi thậm chí không cố tạo danh sách. Tất cả những gì tôi đang cố gắng làm ở đây là mang lại những chỗ ở có liên quan đến một địa điểm (nơi tên địa điểm trong bảng Place được liên kết với bảng Chỗ ở qua bảng AccommodationPlaceJoin) tương đương với bất kỳ tên địa điểm nào trong tiêu chí .Locations (thuộc loại IList).

Tôi đã thử thay đổi dòng này thành điều này, nhưng nó không hoạt động.

(criteria.Locations == null || 
criteria.Locations.Count == 0 || 
a.AccommodationPlaceJoins.Any(j => criteria.Locations.Any(l => l == j.Place.PlaceName))) 

Trả lời

29

Giá trị không đổi EF không thể tạo là null để so sánh criteria.Locations == null. Bạn cần để phân chia các truy vấn vào hai trường hợp và làm việc kiểm tra để xem danh sách sản phẩm nào bên ngoài của truy vấn, ví dụ như vậy:

var result = DataContext.Accommodations.Where(a => 
    (criteria.MinPrice == null || 
     a.AccommodationRates.Any(r => r.From >= criteria.MinPrice)) && 
    (criteria.MaxPrice == null || 
     a.AccommodationRates.Any(r => r.To <= criteria.MaxPrice))); 

if (criteria.Locations != null && criteria.Locations.Count > 0) 
{ 
    result = result.Where(a => a.AccommodationPlaceJoins 
     .Any(j => criteria.Locations.Contains(j.Place.PlaceName))); 
} 

Sửa

BTW: Soạn toàn bộ truy vấn sẽ làm cho nó tốt hơn có thể đọc được theo ý kiến ​​của tôi và sẽ đơn giản hóa SQL mà phải được gửi đến cơ sở dữ liệu:

IQueryable<Accommodation> result = DataContext.Accommodations; 

if (criteria.MinPrice != null) 
    result = result.Where(a => a.AccommodationRates 
     .Any(r => r.From >= criteria.MinPrice)); 

if (criteria.MaxPrice != null) 
    result = result.Where(a => a.AccommodationRates 
     .Any(r => r.To <= criteria.MaxPrice)); 

if (criteria.Locations != null && criteria.Locations.Count > 0) 
    result = result.Where(a => a.AccommodationPlaceJoins 
     .Any(j => criteria.Locations.Contains(j.Place.PlaceName))); 
+0

Wow, một câu trả lời tuyệt vời là gì. Cảm ơn rất nhiều. Tôi đã đi xuống rất nhiều câu hỏi sai. Cảm ơn câu trả lời +1 và được chấp nhận và câu hỏi yêu thích. Không có thắc mắc bạn có gần 29K điểm. Tại sao điều này xảy ra? –

+0

Tôi đang tái cấu trúc phù hợp với đề xuất khả năng đọc của bạn. Cảm ơn bạn. –

+1

@SachinKainth: Ngoại lệ xảy ra bởi vì trong LINQ to Entities, mỗi phân đoạn biểu thức và biểu thức trong truy vấn phải được dịch thành SQL. So sánh 'criteria.Locations == null' không được thực hiện ở phía client (= .NET) nhưng thay vào đó EF cũng muốn dịch nó thành SQL và sau đó cơ sở dữ liệu được cho là thực hiện so sánh. Nhưng cơ sở dữ liệu không biết cách so sánh các tham chiếu đối tượng .NET/CLR, nó chỉ có thể kiểm tra các kiểu nguyên thủy như chuỗi, int, vv cho 'NULL'. Không dịch sang SQL có thể hoặc được hỗ trợ -> Ngoại lệ. – Slauma

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