LINQ Group by返回不期望的和0

aydmsdu9  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(93)

我有一个这样的程序在这个小提琴https://dotnetfiddle.net/bkuPEZ可用:

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
                
public class Program
{
    public static void Main()
    {
        List<Animals> animalList = new List<Animals>()
        {
             new Animals() { AnimalType = "Lion", FoodRatio = 5, PreferredFood = "meat", FruitRatio = 5},
             new Animals() { AnimalType = "Tiger", FoodRatio = 4 , PreferredFood = "meat", MeatRatio = 5 },
             new Animals() { AnimalType  = "Giraffe", FoodRatio = 3, PreferredFood = "fruit", FruitRatio = 2 }, 
             new Animals() { AnimalType = "Piranha", FoodRatio = 5, PreferredFood = "fruit", MeatRatio = 2 },
             new Animals() { AnimalType = "Piranha", FoodRatio = 5, PreferredFood = "meat", FruitRatio = 2 }
        };

        List<Prices> priceList = new List<Prices>() 
        {
            new Prices() { FoodType = "meat", Price = 1000 },
            new Prices() { FoodType = "fruit", Price = 2000 }
        };

        var totalCost = (from animal in animalList 
           join price in priceList
           on animal.PreferredFood equals price.FoodType
           group new { Animal = animal, Price = price } by animal.AnimalType into g
           select new 
            {
                AnimalType = g.Key,
                Price = g.Sum(x => x.Price.Price * x.Animal.FruitRatio + x.Animal.MeatRatio * x.Price.Price)
            }).ToList();
    
          Console.WriteLine(JsonConvert.SerializeObject(totalCost.ToList(), Formatting.Indented));
    }
}

public class Prices
{
    public string FoodType { get; set; }
    public decimal Price { get; set; }
}

internal class Animals
{
    public string AnimalType { get; set; }
    public decimal FoodRatio { get; set; }
    public string PreferredFood { get; set; }
    public string? OmnivoreMeatRatio { get; set; }
    public decimal? MeatRatio { get; set; }
    public decimal? FruitRatio { get; set; }
}

字符串
我想实现的是计算购买每种动物所需的FruitRatio和MeatRatio的价格。有些动物既吃水果又吃肉,我试图通过将它们分成两个元素来解决这个问题(如本例中的Piranha)。
我的预期输出是:
动物价格狮子10000老虎5000长颈鹿4000食人鱼5000
但我使用LINQ的输出是:

[
  {
    "AnimalType": "Lion",
    "Price": 0.0
  },
  {
    "AnimalType": "Tiger",
    "Price": 0.0
  },
  {
    "AnimalType": "Giraffe",
    "Price": 0.0
  },
  {
    "AnimalType": "Piranha",
    "Price": 0.0
  }
]

xeufq47z

xeufq47z1#

在.NET中,具有null的操作数给予null:

decimal? result = null + 2m;
// result is null

字符串
在每种动物中,MeatRatioFruitRatio都没有定义,那么它取默认值decimal?为null。
然后这个表达式每次返回null:

x => x.Price.Price * x.Animal.FruitRatio + x.Animal.MeatRatio * x.Price.Price


null的和是零,所以你的结果。
解决方案是为MeatRatioFruitRatio定义一个非空值。

internal class Animals
{
    public string AnimalType { get; set; }
    public decimal FoodRatio { get; set; }
    public string PreferredFood { get; set; }
    public string? OmnivoreMeatRatio { get; set; }
    public decimal MeatRatio { get; set; } // non nullable, the default value is zero
    public decimal FruitRatio { get; set; }  // non nullable, the default value is zero
}


另一个解决方案是修改如下表达式:

x => x.Price.Price * (x.Animal.FruitRatio ?? 0) + (x.Animal.MeatRatio ?? 0) * x.Price.Price

w8biq8rn

w8biq8rn2#

试着用以下方式计算价格:
第一个月

相关问题