我有一个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>
属性。
我正在尝试做什么,如果是,怎么做?
谢谢。
答案 0 :(得分:11)
你正在调用ToList内部变成一个更大的查询。删除对.ToList()的调用。
问题是查询中的所有内容都变成了一个大的表达式树,实体框架试图将其转换为SQL语句。从“SQL”的角度来看,“ToList”没有任何意义,所以你不应该在里面的任何地方调用它。
在大多数情况下,您希望在返回整个查询之前调用ToList,以确保评估查询并将结果加载到内存中。在这种情况下,您只返回一个对象,因此对First
的调用基本上是相同的。
RecipeCategories对List<RecipeCategoryItem>
有多重要?如果您可以改为IEnumerable,那么您可以毫无问题地删除对ToList
的调用。
如果您必须拥有List
,那么首先需要使用初始实体框架查询和匿名类型(不调用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();
请注意,最后一个示例将导致两次数据库跳转,但会导致更少的数据通过线路发送。
答案 1 :(得分:2)
我想我有一个问题的解决方案。使用动态类型。
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();
答案 2 :(得分:0)
尝试:
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();