具有分组的笛卡尔积

时间:2011-04-19 09:25:25

标签: c# .net linq .net-4.0

这是我昨天问过的一个问题的后续行动 - Left outer join and group by。我在这个问题上的要求略有不妥。

我真正需要的是年份和项目的笛卡尔积,并为每个配对生成一个值。所以,而不是使用左连接来获取(例如):

Year    Name    Value  
1       A       100  
1       B       300  
2       A       150  
2       B       200  
3       (NONE)  0  
4       A       50  

我需要确保每年有1行和我的2个列表中的项目,如果没有对应于给定年份的项目,则将值设置为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)

我已经尝试修改了给另一个问题的2个答案,但似乎最终得到每年X个行/项目对,其中X是不同项目的数量。

1 个答案:

答案 0 :(得分:2)

我认为没有任何好方法(仅在LINQ内)。您可以先找到不同的名称,获取年份的笛卡尔积和这些名称,然后加入您的数据。

p.s。,您应该将Price字段的类型更改为十进制(我将在此处假设),并将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;