搜索很多,但没有为我找到任何合适的解决方案。我在lambda expression
中引入了一个变量,这就是显示此错误消息的原因。此外,我可以解决编写“SQL Like Linq Query”的问题,但这不是我的期望。我期望在“Linq使用Lambda表达式”中引入变量。可能吗?
带有语句主体的lambda表达式无法转换为表达式树。
这是我的代码:
IQueryable<IGrouping<int, AnimalFood>> animalFoods = db.AnimalFoods.GroupBy(x => x.FoodId);
IQueryable<FoodSummaryViewModel> foodSummaryViewModel = animalFoods.Select(g =>
{
var animalFood = g.FirstOrDefault();
return new FoodSummaryViewModel()
{
FoodName = animalFood.Food.FoodName,
FoodPrice = animalFood.Food.UnitPrice,
TotalFoodQuantity = g.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity),
TotalPrice = g.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity) * animalFood.Food.UnitPrice
};
});
return foodSummaryViewModel.ToList();
答案 0 :(得分:3)
错误信息非常清楚:你有一个带有语句体的lambda表达式,并且它根本无法转换为表达式树(至少不是由编译器自动转换)。因此,您的linq提供程序无法从中创建查询以发送到数据库(即使您手动创建表达式树,这不是一件容易的事,您的linq提供程序也无法将其转换为SQL查询)。
您有两种选择。选项一是重写您的查询,使其不包含语句体,正如其他人所示。
另一个选项是使用linq到对象在内存中执行部分查询。您必须小心这种方法,并避免从数据库中获取太多数据。但这样做的方法是:
IEnumerable<IGrouping<int, AnimalFood>> animalFoods =
db.AnimalFoods.GroupBy(x => x.FoodId).AsEnumerable();
IEnumerable<FoodSummaryViewModel> foodSummaryViewModel = animalFoods.Select(g =>
{
var animalFood = g.FirstOrDefault();
return new FoodSummaryViewModel()
{
FoodName = animalFood.Food.FoodName,
FoodPrice = animalFood.Food.UnitPrice,
TotalFoodQuantity = g.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity),
TotalPrice = g.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity) * animalFood.Food.UnitPrice
};
});
return foodSummaryViewModel.ToList();
这可能会给你你想要的东西,但它可能不是一个好主意。您的选择器正在使用AnimalFood.Animal.AnimalQuatity
属性链,这可能会导致延迟加载,具体取决于您的Linq提供程序。如果你已将其配置为使用预先加载,那么你可能不会更好,因为你可能会加载过多的数据。
所以你可能会更好地重写你的查询。你确定这样的事情不起作用吗?
var q = from food in db.Foods
select new FoodSummaryViewModel
{
FoodName = food.FoodName,
FoodPrice = food.UnitPrice,
TotalFoodQuantity = (from fa in food.AnimalFoods
select fa.Animal.AnimalQuantity).Sum() * food.FoodQuantity
TotalPrice = (from fa in food.AnimalFoods
select fa.Animal.AnimalQuantity).Sum() * food.FoodQuantity * food.UnitPrice
};
return q.ToList();
答案 1 :(得分:0)
您无法在linq-2-db查询中编写多行方法,因为这种多行方法无法转换为表达式树,而不是由提供程序解释并因此转换进入纯SQL语句。你可以这样做:
var results = (from f in animalFoods
group f by f.FoodId into groups
let animalFood = groups.First()
select new FoodSummaryViewModel()
{
FoodName = animalFood.Food.FoodName,
FoodPrice = animalFood.Food.UnitPrice,
TotalFoodQuantity = groups.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity),
TotalPrice = groups.Sum(x => x.Animal.AnimalQuantity * x.FoodQuantity) * animalFood.Food.UnitPrice
}).ToList();