2010-10-02 19 views
68

tôi thấy công việc mã này với LINQ to SQL nhưng khi tôi sử dụng Entity Framework, nó throws lỗi này:Phương pháp không thể được dịch sang một biểu hiện cửa hàng

LINQ to Entities does not recognize the method 'System.Linq.IQueryable'1[MyProject.Models.CommunityFeatures] GetCommunityFeatures()' method, and this method cannot be translated into a store expression.`

Mã kho là thế này:

public IQueryable<Models.Estate> GetEstates() 
{ 
    return from e in entity.Estates 
      let AllCommFeat = GetCommunityFeatures() 
      let AllHomeFeat = GetHomeFeatures() 
      select new Models.Estate 
         { 
           EstateId = e.EstateId, 
           AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat), 
           AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat) 
         }; 
} 

public IQueryable<Models.CommunityFeatures> GetCommunityFeatures() 
{ 
    return from f in entity.CommunityFeatures 
      select new CommunityFeatures 
         { 
          Name = f.CommunityFeature1, 
          CommunityFeatureId = f.CommunityFeatureId 
         }; 
} 

public IQueryable<Models.HomeFeatures> GetHomeFeatures() 
{ 
    return from f in entity.HomeFeatures 
      select new HomeFeatures() 
      { 
       Name = f.HomeFeature1, 
       HomeFeatureId = f.HomeFeatureId 
      }; 
} 

LazyList là một Danh sách mở rộng sức mạnh của IQueryable.

Ai đó có thể giải thích tại sao lỗi này xảy ra?

Trả lời

96

Lý do: Theo thiết kế, LINQ to Entities đòi hỏi sự biểu thức truy vấn LINQ toàn được dịch sang một truy vấn máy chủ. Chỉ một vài biểu thức con không tương quan (biểu thức trong truy vấn không phụ thuộc vào kết quả từ máy chủ) được đánh giá trên máy khách trước khi truy vấn được dịch. Các lời gọi phương thức tùy ý không có bản dịch đã biết, như GetHomeFeatures() trong trường hợp này, không được hỗ trợ.
Để cụ thể hơn, LINQ to Entities chỉ hỗ trợ Nhà thầu không tham sốTrình khởi tạo.

Giải pháp: Vì vậy, để vượt qua ngoại lệ này, bạn cần phải hợp nhất truy vấn phụ của bạn vào một trong những chính cho GetCommunityFeatures()GetHomeFeatures() thay vì trực tiếp gọi phương pháp từ bên trong các truy vấn LINQ. Ngoài ra, có một vấn đề trên các dòng mà bạn đang cố gắng tạo một phiên bản mới của LazyList sử dụng các nhà thầu được tham số hóa của nó, giống như bạn có thể đang thực hiện trong LINQ to SQL. Cho rằng giải pháp sẽ được chuyển sang đánh giá khách hàng của các truy vấn LINQ (LINQ to Objects). Điều này sẽ yêu cầu bạn gọi phương thức AsEnumerable cho các truy vấn LINQ to Entities của bạn trước khi gọi hàm tạo LazyList.

Something như thế này nên làm việc:

public IQueryable<Models.Estate> GetEstates() 
{ 
    return from e in entity.Estates.AsEnumerable() 
     let AllCommFeat = from f in entity.CommunityFeatures 
         select new CommunityFeatures { 
          Name = f.CommunityFeature1, 
          CommunityFeatureId = f.CommunityFeatureId 
         }, 
     let AllHomeFeat = from f in entity.HomeFeatures 
         select new HomeFeatures() { 
          Name = f.HomeFeature1, 
          HomeFeatureId = f.HomeFeatureId 
         }, 
     select new Models.Estate { 
      EstateId = e.EstateId, 
      AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat), 
      AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat) 
     }; 
} 


More Info: Hãy xem tại LINQ to Entities, what is not supported? để biết thêm. Ngoài ra, hãy xem LINQ to Entities, Workarounds on what is not supported để có cuộc thảo luận chi tiết về các giải pháp khả thi. (Cả hai liên kết đều là phiên bản được lưu trong bộ nhớ cache vì trang web gốc bị hỏng)

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