从Linq查询创建多个结果

时间:2011-09-07 03:15:31

标签: c# linq

我有一个相当独特的情况,我以前从未需要这个。我有一个Linq查询,使用EF4.1从数据库返回数据。我想从每个查询结果中创建多个相似(相同签名)的匿名(或者甚至在必要时命名)结果。

这是我现在使用的代码:

var data = getMyData().Select(x => 
              new 
              {
                GoalName = x.GoalType.Name, 
                Start = x.StartDate, 
                End = x.EndDate, 
                x.StartValue, 
                x.CheckIns
              }).ToList();

var r1 = data.Select(x => 
              new 
              { 
                title = x.GoalName, 
                start = x.Start.ToString(), 
                end = x.End.ToString(), 
                className = "hidden", 
                type = "goal"
              });

var r2 = data.Select(x => 
              new 
              { 
                title = string.Format("Start: {0:0.##}", x.StartValue), 
                start = x.Start.ToString(), 
                end = x.Start.ToString(), 
                className = "", 
                type = "" 
              });

var r3 = data.Select(x => 
              new 
              { 
                title = "End", 
                start = x.End.ToString(), 
                end = x.End.ToString(), 
                className = "", 
                type = "" 
              });

var r4 = data.SelectMany(x => x.CheckIns)
           .Select(y => 
              new 
              { 
                title = y.CheckInValue.Value.ToString(), 
                start = y.CheckInDateTime.ToString(), 
                end = y.CheckInDateTime.ToString(), 
                className = "", 
                type = "" 
              });

var result = r1.Union(r2).Union(r3).Union(r4);

现在也许这就像任何一种方式一样好,但我不禁感到我错过了什么。

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:3)

您可以使用yield创建一个迭代器,它也具有被懒惰地评估的优点(不需要ToList())。我创建了一个类型化的类Result来保存查询结果

private IEnumerable<Result> PerformQuery()
{
    var results= getMyData().Select(x => new {GoalName = x.GoalType.Name, 
   Start = x.StartDate, End = x.EndDate, x.StartValue, x.CheckIns});

    foreach (var result in results)
    {
          yield return new Result() { Title = result.GoalName, Start = result.Start.ToString(), End = result.End.ToString(), ClassName = "Hidden", Type = "Goal" };

          yield return new Result() { Title = String.Format("Start: {0:0.##}",result.StartValue), Start = result.Start.ToString(), End = result.Start.ToString() }

          yield return new Result() { Title = "End", Start = result.End.ToString(), End = result.End.ToString() };

          foreach (var checkIn in result.CheckIns)
               yield return new Result() { Title = checkIn.CheckInValue.Value.ToString(), Start = checkIn.CheckInDateTime.ToString(), End = checkIn.CheckInDateTime.ToString() };
    }
}

答案 1 :(得分:3)

我认为你的确是好的。

但StevenzNPaul的建议并不是那么糟糕,以下是如何使用let关键字存储不同的投影,然后单独选择结果(为简洁起见,我没有预测所有字段,但是你明白了):

var query = from x in data
            let result1 = new {title = x.GoalName, start = x.Start}
            let result2 = new {title = string.Format("Start: {0:0.##}", x.StartValue), start = x.Start}
            let result3 = new {title = "End", start = x.End}
            let checkins = x.CheckIns.Select(checkin => new { title = "...", start = checkin.Start })
            from result in new[] { result1, result2, result3 }.Concat(checkins)
            select result;

显然,这是否更好是一个偏好问题。此外,这将导致不同的排序,这对您来说可能是也可能不是问题。

答案 2 :(得分:1)

尝试使用let关键字它会对你有用。