如何在linq中创建带填充行的数据集?

时间:2012-08-11 00:11:55

标签: linq

如果我有这样的清单:

var teams = new List() { "Team A", "Team B", "Team C" };

我的数据集如下:

var scores = new List<scoredata> {
    new scoredata() { Team = 'Team A', Date = '1/1/2012', Value = 1 }, 
    new scoredata() { Team = 'Team B', Date = '1/1/2012', Value = 1 }, 
    new scoredata() { Team = 'Team C', Date = '1/1/2012', Value = 1 }, 
    new scoredata() { Team = 'Team A', Date = '1/2/2012', Value = 2 }, 
    new scoredata() { Team = 'Team B', Date = '1/3/2012', Value = 3 }, 
    new scoredata() { Team = 'Team C', Date = '1/4/2012', Value = 4 }
}

是否可以构建一个看起来像这样的数据集?

Team A, '1/1/2012', 1
Team B, '1/1/2012', 1
Team C, '1/1/2012', 1
Team A, '1/2/2012', 2
Team B, '1/2/2012', null
Team C, '1/2/2012', null
Team A, '1/3/2012', null
Team B, '1/3/2012', 3
Team C, '1/3/2012', null
Team A, '1/4/2012', null
Team B, '1/4/2012', null
Team C, '1/4/2012', 4

我不确定这是什么,但我想在最终数据集中填写空白日期和分数,以便它始终返回每个日期的所有团队,但如果分数数据不可用则返回null。

2 个答案:

答案 0 :(得分:3)

var dates = scores.Select(s => s.Date).Distinct();

var result =    
    from date in dates
    from team in teams
    let teamScores = scores.Where(s => s.Team == team && s.Date == date)
    orderby date
    select new { team, date, Score = teamScores.FirstOrDefault() };

虽然没有与编译器核实,试一试。

答案 1 :(得分:2)

使用纯LINQ到对象。

public class ScoreData
{
    public string Team { get; set; }
    public string Date { get; set; }
    public int? Value { get; set; }
}
var teams = new[] { "Team A", "Team B", "Team C" };
var scores = new[]
{
    new ScoreData { Team = "Team A", Date = "1/1/2012", Value = 1 }, 
    new ScoreData { Team = "Team B", Date = "1/1/2012", Value = 1 }, 
    new ScoreData { Team = "Team C", Date = "1/1/2012", Value = 1 }, 
    new ScoreData { Team = "Team A", Date = "1/2/2012", Value = 2 }, 
    new ScoreData { Team = "Team B", Date = "1/3/2012", Value = 3 }, 
    new ScoreData { Team = "Team C", Date = "1/4/2012", Value = 4 },
};

var dates = scores.Select(score => score.Date).Distinct();
var query =
    from date in dates
    from team in teams
    join score in scores
        on new { Team = team, Date = date }
        equals new { score.Team, score.Date }
        into filteredScores
    let defaultScore = new ScoreData
    {
        Team = team,
        Date = date,
        Value = null,
    }
    from score in filteredScores.DefaultIfEmpty(defaultScore)
    select score;

请注意,这很可能在LINQ to SQL或LINQ to Entities中无法正常工作,需要进行一些调整。