C# 分组笛卡尔积

C# 分组笛卡尔积,c#,.net,linq,.net-4.0,C#,.net,Linq,.net 4.0,这是我昨天问的一个问题的后续行动-。在那个问题上我的要求有点错误 我真正需要的是一个年和项目的笛卡尔乘积,每个配对产生一个值。因此,不要使用左连接来获取(例如): 我需要确保我的2个列表中每年有1行和项目,如果没有与给定年份对应的项目,则将值设置为0。上述内容将成为: Year Name Value 1 A 100 1 B 300 2 A 150 2 B 200 3

这是我昨天问的一个问题的后续行动-。在那个问题上我的要求有点错误

我真正需要的是一个年和项目的笛卡尔乘积,每个配对产生一个值。因此,不要使用左连接来获取(例如):

我需要确保我的2个列表中每年有1行和项目,如果没有与给定年份对应的项目,则将值设置为0。上述内容将成为:

Year    Name    Value  
1       A       100  
1       B       300  
2       A       150  
2       B       200  
3       A       0 (data for year 3 is missing for item A, so include a 0 valued row)
3       B       0 (data for year 3 is missing for item B, so include a 0 valued row)  
4       A       50  
4       B       0 (data for year 4 is missing for item B, so include a 0 valued row)

我试图修改对另一个问题给出的两个答案,但结果似乎是每年的行数/项目对为X,其中X是不同项目的数量。

我认为没有任何好的方法(仅在LINQ中)。你可以先找到不同的名字,得到年份和这些名字的笛卡尔乘积,然后把你的数据结合起来

p、 在美国,您应该将
Price
字段的类型更改为decimal(我将在这里假设),并可能将
Quantity
更改为整数类型

var now = DateTime.Now;
var altData = myData
    .Select(data => new
    {
        Year = (data.Expiration.Year - now.Year) + 1,
        data.Name,
        Value = Decimal.Multiply(data.Quantity, data.Price),
    });
var names = myData.Select(data => data.Name).Distinct();
var years = Enumerable.Range(1, 20);
var query = from Year in years
            from Name in names
            join data in altData
                on new { Year, Name }
                equals new { data.Year, data.Name }
                into joined
            from data in joined.DefaultIfEmpty(new { Year, Name, Value = 0M })
            select data;

谢谢完全按照要求工作。
var now = DateTime.Now;
var altData = myData
    .Select(data => new
    {
        Year = (data.Expiration.Year - now.Year) + 1,
        data.Name,
        Value = Decimal.Multiply(data.Quantity, data.Price),
    });
var names = myData.Select(data => data.Name).Distinct();
var years = Enumerable.Range(1, 20);
var query = from Year in years
            from Name in names
            join data in altData
                on new { Year, Name }
                equals new { data.Year, data.Name }
                into joined
            from data in joined.DefaultIfEmpty(new { Year, Name, Value = 0M })
            select data;