繁体   English   中英

带有语句体的 lambda 表达式无法转换为表达式树(Lambda 和 Linq)

[英]A lambda expression with a statement body cannot be converted to an expression tree(Lambda and Linq)

搜索了很多,但没有找到任何适合我的解决方案。 我在lambda expression引入了一个变量,这就是显示此错误消息的原因。 此外,我可以解决编写“SQL Like Linq Query”的问题,但这不是我的期望。我的期望是在“Linq Using Lambda Expression”中引入变量。 有没有可能??

带有语句体的 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();

错误消息非常清楚:您有一个带语句主体的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();

您不能在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();

Antes de hacer el Select Convierte el resultado en lista。

示例:

IQueryable<IGrouping<int, AnimalFood>> animalFoods = db.AnimalFoods.GroupBy(x => x.FoodId);
IQueryable<FoodSummaryViewModel> foodSummaryViewModel = animalFoods.ToList().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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM