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