2010-09-16 5 views
6

Tôi có truy vấn LINQ to EF trả về dữ liệu ở dạng lớp. Lớp học có thuộc tính List<RecipeCategories> mà tôi cần điền. Bảng RecipeCategories là một bảng quan hệ giữa bảng Công thức và bảng RecipeCategories, và có thể là nhiều bảng. Tôi tìm thấy đủ thông tin để lấy mã để biên dịch, nhưng nó sai sót trong thời gian chạy và tôi đã không thể tìm ra cách để có được quyền này.Lấy bộ sưu tập phụ trong Danh sách <class> biểu mẫu

ri = (from r in recipeData.Recipes 
       where r.ID == recipeId 
       select new RecipeItem 
       { 
        Id = r.ID, 
        ProductId = r.Product.ID, 
        RecipeName = r.recipeName, 
        RecipeDescription = r.recipeDescription, 
        Servings = r.servings.HasValue ? r.servings.Value : 0, 
        CreatedDate = r.createdDate, 
        PrepTime = r.prepTime.HasValue ? r.servings.Value : 0, 
        CookTime = r.cookTime.HasValue ? r.servings.Value : 0, 
        Approved = r.approved, 
        RecipeInstructions = r.recipeInstructions, 
        RecipeIngredients = r.recipeIngredients, 
        RecipeCategories = r.RecipeCategories.Select(i => new RecipeCategoryItem { Id = i.ID, CategoryName = i.categoryName }).ToList() 
       }).First(); 

Đây là lỗi tôi nhận được.

LINQ to Entities không nhận ra phương pháp 'System.Collections.Generic.List 1[RecipeCategoryItem] ToList[RecipeCategoryItem](System.Collections.Generic.IEnumerable 1 [RecipeCategoryItem])' và phương pháp này không thể được dịch sang biểu thức cửa hàng.

Phần mà tôi đang làm là dòng này.

RecipeCategories = r.RecipeCategories.Select(i => new RecipeCategoryItem { Id = i.ID, CategoryName = i.categoryName }).ToList() 

Công thức Danh mục là tài sản List<RecipeCategoryItem>.

Là những gì tôi đang cố gắng làm điều đó, và nếu có thì làm cách nào?

Cảm ơn bạn.

Trả lời

11

Bạn đang gọi ToList bên trong nội dung được chuyển thành truy vấn lớn hơn. Xóa cuộc gọi tới .ToList().

Vấn đề là mọi thứ trong truy vấn của bạn được chuyển thành một cây biểu thức lớn, mà Entity Framework cố gắng dịch sang câu lệnh SQL. "ToList" không có ý nghĩa gì từ một quan điểm SQL, vì vậy bạn không nên gọi nó ở bất cứ đâu bên trong truy vấn của bạn.

Trong hầu hết các trường hợp, bạn muốn gọi ToList trên truy vấn tổng thể của bạn trước khi trả về, để đảm bảo rằng truy vấn được đánh giá và kết quả được tải vào bộ nhớ. Trong trường hợp này, bạn chỉ trả về một đối tượng, do đó, cuộc gọi đến First thực chất là giống nhau.

Làm thế nào quan trọng là RecipeCategories là List<RecipeCategoryItem>? Nếu bạn có thể làm cho IEnumerable thay thế, bạn có thể xóa cuộc gọi đến ToList mà không gặp bất kỳ sự cố nào.

Nếu bạn cần List, thì trước tiên bạn cần phải lấy tất cả thông tin bằng cách sử dụng truy vấn khung thực thể ban đầu và loại ẩn danh (không gọi ToList), sau đó chuyển dữ liệu bạn nhận được vào đối tượng loại bạn muốn trước khi trả lại.

Hoặc bạn có thể xây dựng RecipeInfo bạn phản đối từng phần từ nhiều truy vấn, như vậy:

var ri = (from r in recipeData.Recipes 
      where r.ID == recipeId 
      select new RecipeItem 
      { 
       Id = r.ID, 
       ProductId = r.Product.ID, 
       RecipeName = r.recipeName, 
       RecipeDescription = r.recipeDescription, 
       Servings = r.servings.HasValue ? r.servings.Value : 0, 
       CreatedDate = r.createdDate, 
       PrepTime = r.prepTime.HasValue ? r.servings.Value : 0, 
       CookTime = r.cookTime.HasValue ? r.servings.Value : 0, 
       Approved = r.approved, 
       RecipeInstructions = r.recipeInstructions, 
       RecipeIngredients = r.recipeIngredients, 
      }).First(); 
var rc = from c in recipeData.RecipeCategories 
     where c.Recipes.Any(r => r.ID == recipeId) 
     select new RecipeCategoryItem 
     { 
      Id = c.ID, CategoryName = c.categoryName 
     }; 
ri.RecipeCategories = ri.ToList(); 

Lưu ý rằng ví dụ cuối cùng này sẽ gây ra hai chuyến đi cơ sở dữ liệu, nhưng sẽ làm cho dữ liệu ít hơn để được gửi qua dây dẫn.

+0

Tôi đã cố gắng cách thứ hai của mình trước đây, nhưng c.Công thức không phơi bày bất kỳ trường nào, và tôi nghĩ đó là vì bảng quan hệ không thực sự hiển thị trong mô hình dữ liệu vì nó là một bảng liên kết giữa các công thức nấu ăn và các danh mục đối ứng. Tôi đã thử cách đầu tiên bạn nói, nhưng tôi không chắc chắn làm thế nào để cấu trúc truy vấn LINQ bây giờ. Đây là những gì tôi có. [CODE] RecipeCategories = r.RecipeCategories.Select (i => new RecipeCategoryItem {Id = i.ID, CategoryName = i.categoryName}) [/ CODE] – Ben

+0

Nhận xét cuối cùng đã hết thời gian chờ. Tôi gặp lỗi này. Không thể chuyển đổi IEnumerable thành RecipeCategoryItems – Ben

+0

@Ben: Có vẻ như Recipes và RecipeCategories có mối quan hệ nhiều-nhiều, sau đó? Tôi đã chỉnh sửa câu trả lời của mình cho phù hợp. Hãy cho tôi biết làm thế nào mà làm việc cho bạn. Với cách đầu tiên tôi đã nói, bạn sẽ cần phải sử dụng một kiểu ẩn danh bằng cách thay đổi 'select new RecipeItem {' to 'select new {'. Sau đó, bước thứ hai của bạn là lấy đối tượng ẩn danh này và tạo một RecipeItem mới dựa trên dữ liệu của nó. – StriplingWarrior

2

Tôi nghĩ rằng tôi có giải pháp cho vấn đề. Sử dụng loại động.

public class BoxImageViewDetailDto 
{ 
    public Guid PropertyId { get; set; } 

    public string Title { get; set; } 
    public string SubTitle { get; set; } 
    public string Description { get; set; } 
    public string SubDescription { get; set; } 

    public decimal? PropertyValue { get; set; } 
    public byte? UnitsFloor { get; set; } 

    public dynamic ImagensRowsVar { get; set; } 
    public List<ImageViewDto> ImagensRows 
    { 
     get 
     { 
      return (List<ImageViewDto>)this.ImagensRowsVar; 
     } 
    } 

    public int ImagensRowsTotal { get; set; } 
} 

CorretorDaVez.DTO.UserControls.BoxImageViewDetailDto c = (from p in entities.rlt_Property 
    join pc in entities.rlt_PropertyPicture on p.PropertyId equals pc.PropertyId 
    where p.PropertyId == propertyId 
    orderby p.CreateDate descending 
    select new CorretorDaVez.DTO.UserControls.BoxImageViewDetailDto 
    { 
     PropertyId = p.PropertyId, 
     Title = p.Title, 
     PropertyValue = p.PropertyValue, 
     Description = p.Description, 
     UnitsFloor = p.UnitsFloor, 
     ImagensRowsTotal = p.rlt_PropertyPicture.Count, 
     ImagensRowsVar = p.rlt_PropertyPicture.Select(s => new CorretorDaVez.DTO.UserControls.ImageViewDto { PropertyId = p.PropertyId, ImagePath = pc.PhotoUrl}) 
    }).FirstOrDefault(); 
0

thử:

 


    var ri = (from r in recipeData.Recipes 
       where r.ID == recipeId 
       select new RecipeItem 
       { 
        Id = r.ID, 
        ProductId = r.Product.ID, 
        RecipeName = r.recipeName, 
        RecipeDescription = r.recipeDescription, 
        Servings = r.servings.HasValue ? r.servings.Value : 0, 
        CreatedDate = r.createdDate, 
        PrepTime = r.prepTime.HasValue ? r.servings.Value : 0, 
        CookTime = r.cookTime.HasValue ? r.servings.Value : 0, 
        Approved = r.approved, 
        RecipeInstructions = r.recipeInstructions, 
        RecipeIngredients = r.recipeIngredients, 
        RecipeCategories = from rc in recipeData.RecipeCategories 
            where rc.Recipes.Any(r => r.ID == recipeId) 
            select new RecipeCategoryItem{ 
               Id = rc.ID, 
               CategoryName = rc.categoryName 
              } 
    ).First();