选择Linq中的子查询

时间:2016-05-07 06:55:27

标签: c# asp.net linq

我的查询如下

var result = from cr in cumulativeresult
    orderby cr.Days
    select new
    {
        Days = cr.Days,
        Com = (from cr1 in cumulativeresult
            where cr1.Days < cr.Days
            group cr1 by 1 into cr1grp
            select
            new
            {
                Count = cr1grp.Count() + cr.Com 
            }),
        ComPercent = Math.Round((double.Parse((
            from cr1 in cumulativeresult
            where cr1.Days < cr.Days
            group cr1 by 1 into cr1grp 
            select cr1grp.Count() + cr.Com).ToString()) / ComCount) * 100, 2)
    };

但是Com和ComPercent并没有作为价值观出现。我如何能够检索其中的值?我检索它们的循环如下

更新

foreach (var item in result)
{
    dt.Rows.Add(item.Days, item.Com, item.ComPercent);
}

我不想对我的foreach循环进行任何处理,我希望我的linq查询中的值。

2 个答案:

答案 0 :(得分:5)

编译器不知道您的子查询将始终返回一行,因为返回类型仍为IEnumerable(或IQueryable)。这可以通过使用First()Single()(或相应的..OrDefault()版本)来解决,但是,更常见的是在没有分组的情况下使用Count(),例如:< / p>

Com = (from cr1 in cumulativeresult
       where cr1.Days < cr.Days
       select cr1
      ).Count() + cr.Com,

您可能还想考虑将子查询移动到let子句中,以便可以重复使用它来计算ComComPercent

var result = from cr in cumulativeresult
             let totalCount = 
                      (from cr1 in cumulativeresult
                       where cr1.Days < cr.Days
                       select cr1
                      ).Count() + cr.Com 
             orderby cr.Days
             select new
             {
                Days = cr.Days,
                Com = totalCount,
                ComPercent = Math.Round((double)totalCount / ComCount * 100, 2)
             };

答案 1 :(得分:1)

要回答您的问题,您需要选择.First的内容,而不是Linq,知道是1的单个分组。

我也以其他几种方式调整了您的查询:

  1. 要获得一些输出,我必须将<更改为<=
  2. 我使用了强制转换而不是重新分析为双倍。
  3. 这是整个LinqPad查询:

    var cumulativeresult = new[] { new { Days = 0, Com = 0 }, new { Days = 1, Com = 1 } };
    var ComCount = cumulativeresult.Count();
    var result = from cr in cumulativeresult
                 orderby cr.Days
                 select new
                 {
                     Days = cr.Days,
                     Com = (from cr1 in cumulativeresult
                            where cr1.Days <= cr.Days
                            group cr1 by 1 into cr1grp
                            select
                              new
                              {
                                  Count = cr1grp.Count() + cr.Com
                              }
                               ).First().Count,
                     ComPercent = Math.Round((//double.Parse(
                               ((double)(
                               from cr1 in cumulativeresult
                               where cr1.Days <= cr.Days
                               group cr1 by 1 into cr1grp
                               select cr1grp.Count() + cr.Com).First())//.ToString())
                               / ComCount) * 100, 2
                               )
                 };
    
    var dt = new DataTable();
    dt.Columns.AddRange(new[] {new DataColumn("Days"),new DataColumn("Com"),new DataColumn("ComPercent")  });
    foreach (var item in result)
    {
        dt.Rows.Add(item.Days, item.Com, item.ComPercent);
    }
    dt.Dump();