Entity framework 无法在IEnumerable中添加/求和字符串值

Entity framework 无法在IEnumerable中添加/求和字符串值,entity-framework,linq,highcharts,sum,Entity Framework,Linq,Highcharts,Sum,最终目标是使用Highcharts显示GrandTotal列。GrandTotal应该是给定报价id的TotalAmount之和。TotalAmount是一个字符串,其值类似于$10.00或10.00。GrandTotal是一个int,但很容易更改。以下是我迄今为止所做的工作 步骤1:将两个IEnumerable列表转换为它们的ViewModel对应项。我在这里将GrandTotal设置为0,因为我不知道数量 var offersConvert = offers .

最终目标是使用Highcharts显示GrandTotal列。GrandTotal应该是给定报价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();
你可以用

Decimal.TryParse("$10.00", NumberStyles.Currency, CultureInfo.CurrentCulture, out var res);
或者在你的LINQ环境下

GrandTotal = Decimal.Parse(o.sharedOffersConvert.TotalAmount, NumberStyles.Currency)
如果o.SahrodOffersConvert.TotalAmount可能为空

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

我仍然不明白为什么最近每个人都对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();
此外,由于偏移量在该查询的生命周期中似乎是一个常量,因此将其添加到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();

GrandTotal=Decimal.Parse$10.00,numberstyle.Currency有效。这使我相信这个调用GrandTotal=Decimal.Parseo.sharedOffersConvert.TotalAmount,NumberStyles.Currency失败了,因为可能存在空值。有办法处理空值吗?好的,看来你的空方法已经起作用了。我现在正试图把这一点转化为詹姆斯·科伦的答案。看起来我这里的问题不止一个谢谢这两种方法都失败了。我认为Decimal.Parse失败是因为TotalAmount中的空值。有没有办法解释这一点?此外,我需要的Id,创建,股票,赎回,名称和要约以及。如何将这些字段添加到Select语句中,从而创建名为totals的组?谢谢谢谢你在这方面的持续帮助。我刚刚添加了您最新的代码片段,但仍然无法使用select语句从sharedOffers访问数据。我在item.OfferId中的OfferId下面有一条红色的曲线,在t.TotalAmount中有TotalAmount。我还需要使用类似的方法来处理TotalAmount中的潜在空值。totals.Sumt=>t.TotalAmount==null?Decimal.Zero:Decimal.Parset=>t.TotalAmount,NumberStyles.currency我看不出在每个记录中有TotalAmount和GrandTotal有什么意义。TotalAmount是每个sharedOffer的总数。GrandTotal是给定报价id的所有总金额之和。