Получить вложенную коллекцию в форме List <class> - PullRequest
6 голосов
/ 16 сентября 2010

У меня есть запрос LINQ to EF, который возвращает данные в форме класса.У класса есть List<RecipeCategories> свойство, которое мне нужно заполнить.Таблица RecipeCategories - это таблица отношений между таблицей Recipe и таблицей RecipeCategories, и может быть много ко многим.Я нашел достаточно информации, чтобы получить код для компиляции, но он выдает ошибки во время выполнения, и я не смог выяснить, как сделать это правильно.

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();

Это ошибка, которую я получаю.

LINQ to Entities не распознает метод «System.Collections.Generic.List 1[RecipeCategoryItem] ToList[RecipeCategoryItem](System.Collections.Generic.IEnumerable 1 [RecipeCategoryItem])», и этот метод нельзя преобразовать в выражение хранилища.

Часть, над которой я работаю, - это строка.

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

RecipeCategories - это свойство List<RecipeCategoryItem>.

Возможно ли то, что я пытаюсь сделать, и если да, токак?

Спасибо.

Ответы [ 3 ]

11 голосов
/ 16 сентября 2010

Вы вызываете ToList внутри того, что превращается в более крупный запрос. Удалить вызов .ToList ().

Проблема в том, что все в вашем запросе превращается в большое дерево выражений, которое Entity Framework пытается преобразовать в оператор SQL. «ToList» не имеет смысла с точки зрения SQL, поэтому не следует называть его где-нибудь внутри вашего запроса.

В большинстве случаев вы хотите вызвать ToList для вашего общего запроса перед его возвратом, чтобы убедиться, что запрос оценен и результаты загружены в память. В этом случае вы возвращаете только один объект, поэтому вызов First по сути делает то же самое.

Насколько важно, чтобы RecipeCategories был List<RecipeCategoryItem>? Если вы могли бы сделать его IEnumerable вместо этого, то вы можете без проблем удалить вызов на ToList.

Если абсолютно необходимо, чтобы у вас был List, то вам сначала нужно получить всю информацию при использовании исходного запроса Entity Framework и анонимных типов (без вызова ToList), а затем преобразовать полученные данные в Тип объекта, который вы хотите, прежде чем его вернуть.

Или вы можете построить свой объект RecipeInfo по частям из нескольких запросов, например так:

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();

Обратите внимание, что этот последний пример вызовет две поездки в базу данных, но приведет к тому, что по сети будет отправлено меньше данных.

2 голосов
/ 13 декабря 2012

Я думаю, у меня есть решение проблемы. Используйте динамический тип.

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 голосов
/ 16 августа 2013

попробуй:



    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();



Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...