无法在IEnumerable

时间:2017-07-10 19:44:10

标签: entity-framework linq highcharts sum

最终目标是使用Highcharts显示GrandTotal列。 GrandTotal应该是给定Offer ID的TotalAmount的总和。 TotalAmount是一个字符串,值类似于$ 10.00或10.00。 GrandTotal是一个int,但很容易改变。这是我到目前为止所做的。

步骤1)将两个IEnumerable列表转换为其ViewModel对应项。我在这里将GrandTotal设置为0因为我不知道金额。

var offersConvert = offers
               .Select(o => new OfferSummaryViewModel
               {
                   Id = o.Id,
                   Name = o.Name,
                   Created = o.Created,
                   Shares = o.Shares,
                   Redemptions = o.Redemptions,
                   GrandTotal = 0
               })
               .ToList();

            var sharedOffersConvert = sharedOffers
              .Select(s => new SharedOfferViewModel
              {
                  OfferId = s.OfferId,
                  //TotalAmount = s.TotalAmount.Replace("$", string.Empty).Replace(",", string.Empty).Trim()
                  TotalAmount = s.TotalAmount
              })
              //.Where(i => i.TotalAmount != null)
              .ToList(); 

步骤2)在要约的ID上加入两个列表。

var data = offersConvert
               .Join(sharedOffersConvert,
               o => o.Id,
               s => s.OfferId,
                (o, s) => new { offersConvert = o, sharedOffersConvert = s })
                .Select(o => new
               {
                   Id = o.offersConvert.Id,
                   Created = o.offersConvert.Created,
                   Shares = o.offersConvert.Shares,
                   Redemptions = o.offersConvert.Redemptions,
                   Name = o.offersConvert.Name,
                   OfferId = o.sharedOffersConvert.OfferId,
                   TotalAmount = o.sharedOffersConvert.TotalAmount,
                   //GrandTotal = Convert.ToInt32(o.sharedOffersConvert.TotalAmount.Replace("$", string.Empty).Replace(",", string.Empty).Trim())
                   //GrandTotal = Convert.ToInt32(Convert.ToDouble(o.sharedOffersConvert.TotalAmount, CultureInfo.InvariantCulture))
               })
                //.Where(o => o.Id == o.OfferId)
               .OrderBy(o => o.Created.Add(offset))
               .ToList();

正如你所知,我试图删除任何美元符号和逗号。我甚至试图修剪空白区域以获得干净的数据。然后我尝试将字符串转换为int值,所以我可以将它们相加。似乎没什么用。我甚至尝试过.GroupBy和其他方法(见下文)。至少使用.GroupBy,我可以访问.Sum运算符。使用另一种方法,当我无法将int转换为ToList()时遇到问题,所以我必须尝试转换ToString()。

.Where(o => o.Id == o.OfferId)
                .GroupBy(g => g.Id)
                .Select(x => new { GrandTotal = x.Sum(o => o.TotalAmount) })

上面的错误:无法将TotalAmount转换为十进制

.Where(i => i.Id == i.OfferId)
                 .Sum(i => Convert.ToInt32(Convert.ToDouble(i.TotalAmount, CultureInfo.InvariantCulture)
                 )).ToString()

有没有人知道如何在TotalAmount中添加/求和字符串值以获得每个商品ID的GrandTotal?

任何帮助我们非常感谢。谢谢!

更新:这有效,但我真的不明白为什么,我认为它不是很干净。我真的找不到很多人们加入两个列表并总结其中一个列的例子。这对我来说似乎很常见,但也许不是。

var data = (from o in offersConvert
                       join s in sharedOffersConvert on o.Id equals s.OfferId
                       orderby o.Created.Add(offset)
                       let k = new
                       {
                           Id = o.Id,
                           Name = o.Name,
                           Created = o.Created,
                           Shares = o.Shares,
                           Redemptions = o.Redemptions
                       }
                       group s by k into totals
                       select new
                       {
                           OfferId = totals.Key.Id,
                           Name = totals.Key.Name,
                           Created = totals.Key.Created,
                           Shares = totals.Key.Shares,
                           Id = totals.Key.Id,
                           Redemptions = totals.Key.Redemptions,
                           GrandTotal = totals.Sum((s => s.TotalAmount == null ? Decimal.Zero : Decimal.Parse(s.TotalAmount, NumberStyles.Currency)))
                       })
            .ToList();

2 个答案:

答案 0 :(得分:1)

您可以使用

Decimal.TryParse("$10.00", NumberStyles.Currency, CultureInfo.CurrentCulture, out var res);

或者在LINQ的上下文中,

GrandTotal = Decimal.Parse(o.sharedOffersConvert.TotalAmount, NumberStyles.Currency)

如果o.sahredOffersConvert.TotalAmount可能为null,

GrandTotal = (o.sharedOffersConvert.TotalAmount ==null) ? Decimal.Zero : Decimal.Parse(o.sharedOffersConvert.TotalAmount, NumberStyles.Currency)

答案 1 :(得分:0)

我仍然感到困惑,为什么每个人最近都对Lambda语法有这种奇怪的迷恋。而这似乎只是你用过的几种手段中的一种,而不是必要的:

var data = (from o in offers
       join s in sharedOffers on o.Id equals s.OfferId
       orderby o.Created.Add(offset)
       select new
            {
                Id = o.Id,
                Created = o.Created,
                Shares = o.Shares,
                Redemptions = o.Redemptions,
                Name = o.Name,
                OfferId = o.OfferId,
                TotalAmount = Decimal.Parse(o.TotalAmount, NumberStyles.Currency)
            })
           .ToList();

此外,由于offset似乎是常量(对于此查询的生命周期),将其添加到Created不会影响排序,并且该位可以被删除

而且,由于看起来您的最终输出只是总计,因此可以进一步减少到:

var data = (from o in offers
       join s in sharedOffers on o.Id equals s.OfferId
       orderby o.Created
       group Decimal.Parse(o.TotalAmount, NumberStyles.Currency) by o.id into totals
       select new
            {
                Id = totals.Key,
                GrandAmount = totals.Sum()
            })
           .ToList();

更新:放回我拿出的东西......这应该有效(我没有你的桌子,所以我无法测试它)

var data = (from o in offers
        join s in sharedOffers on o.Id equals s.OfferId
        orderby o.Created.Add
        group o by o.Id into totals
        let item = totals.First()
        select new
        {
            Id = item.Id,
            Created = item.Created,
            Shares = item.Shares,
            Redemptions = o.Redemptions,
            Name = item.Name,
            OfferId = item.OfferId,
            GrandTotal = totals.Sum(t=>Decimal.Parse(t.TotalAmount, NumberStyles.Currency))
        })
       .ToList();