簡體   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