2016-09-17 203 views
1

搜索很多,但没有找到适合我的解决方案。我在lambda expression中引入了一个变量,这就是显示此错误消息的原因。此外,我可以解决编写“SQL Like Linq Query”的问题,但这不是我的期望。我的期望是在“Linq使用Lambda表达式”中引入变量。这可能吗?带有语句正文的lambda表达式无法转换为表达式树(Lambda和Linq)

带有语句正文的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(); 
+1

的[“与语句体lambda表达式不能转换为表达式树”]可能的复制(http://stackoverflow.com/questions/5179341/a-lambda-expression-with-a-statement-body-can-be-conversion-to-a-expression) –

回答

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

错误OP越来越与db查询翻译无关。这是编译时错误。 –

+0

谢谢!!我知道这个解决方案..这不是我的期望..我想在“Linq使用Lamda表达式”而不是在“SQL Like Linq查询”中引入变量 – TanvirArjel

+0

@IvanStoev错误是* lambda表达式与语句正文不能转换为表达式树*。你为什么认为这个编译错误是有史以来创建的? – user3185569

2

的错误信息是非常明确的:你有一个说法身体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(); 
+0

非常感谢您的解释! – TanvirArjel