Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从Linq查询创建多个结果_C#_Linq - Fatal编程技术网

C# 从Linq查询创建多个结果

C# 从Linq查询创建多个结果,c#,linq,C#,Linq,我有一个相当独特的情况,我从来没有想过要这样做。我有一个Linq查询,它使用EF4.1从数据库返回数据。我想从每个查询结果中创建多个类似的相同签名匿名,甚至命名(如果需要) 下面是我现在使用的代码: var data = getMyData().Select(x => new { GoalName = x.GoalType.Name, Start = x.Start

我有一个相当独特的情况,我从来没有想过要这样做。我有一个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);
现在也许这是一个很好的方法,但我忍不住觉得我错过了什么


有更好的解决方案吗?

尝试使用let关键字,它会对您有效。

您可以使用yield创建一个迭代器,该迭代器还具有惰性评估的优点,不需要ToList。我创建了一个类型化的类结果来保存查询结果

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() };
    }
}

我想你的一切都还可以

但是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;

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

您可能希望重新格式化代码,以便让愿意帮助您的人更容易阅读。此外,您能否澄清您试图返回的内容?@Chris Pietschmann-代码已经格式化,只是行间没有空格。我想这是个人喜好。在任何情况下,从代码中可以明显看出我得到了什么,并且代码运行良好。我只是在寻找一种功能完全相同但效率更高的产品。你为什么用Union而不是Concat?看起来你只是想把它们连接起来,而不是计算它们的集合并集,这涉及到相互比较它们是否相等,对吗?我在ToString上的观点是,你不需要在很多地方这样做:你可以在第一次选择时这样做,或者,您可以在末尾添加另一个Select来执行此操作。让我们不要执行我需要的操作。Let允许您使用多个查询进行一个查询。我想要相反的方法,一个查询和多个结果集投射回一个结果中。这是一种有趣的方法,但似乎没有添加额外的抽象层,因此速度稍慢。我接受更正。我明白你的意思。这段代码看起来可能会导致创建几个额外的对象以及更多的选择。无论如何,这是一个有趣的解决方案。我认为它不会创建更多的对象。主要区别在于,使用此解决方案,您只需在输入列表数据上循环一次。额外的选择只会为“for循环体”添加更多权重。