提问人:Kip M. 提问时间:10/30/2023 最后编辑:dbcKip M. 更新时间:11/1/2023 访问量:90
如何循环遍历 IEnumerable List 如果有任何重复项,请对每个重复项的值求和,并在 MVC C 中删除 ASP.Net 重复项#
How to Loop through IEnumerable List and if there are any duplicates, sum a value each duplicate has and remove the duplicates in ASP.Net MVC C#
问:
我有一个库存使用情况页面,其中填充了我在特定时间段(例如一个月左右)内使用过的物品列表。有大量重复的项目,我试图在视图页面(IEnumerable List)上放置一个按钮,该按钮将使用项目及其总数列表填充pdf。我无法弄清楚的是如何遍历项目列表,如果有任何重复项,请获取“AmtTaken”值并将它们相加,然后删除重复项,其中它只显示每个项目一次,但“AmtTaken”总数相加在一起。 我现在没有太多代码可以删除,因为我被困住了,并试图找出最好的方法来做到这一点。它来自名为“InventoryUsage”的数据库表。
这是我的模型:
public partial class InventoryUsage
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Display(Name = "Item Code")]
public string Item_Code { get; set; }
[Display(Name = "Amt Taken")]
public string Amt_Taken { get; set; }
[Display(Name = "Submitted?")]
public Nullable<bool> Submitted { get; set; }
}
因此,我正在寻找的重复项是具有相同Item_Code的任何重复项,如果存在重复项,则将Amt_Taken值相加。我仍然希望它列出所有没有重复的项目。我目前如何设置它是“已提交”== false 的所有项目。因此,使用此模型,如果存在重复项,则 ID 将不相同,因此这是另一件让我失望的事情。
这是我的视图页面:
@model IEnumerable<MyApp.Models.InventoryUsage>
<div class="wrapper">
<table class="table">
<tr>
<th>
Item/RM Code
</th>
<th>
Amt Taken
</th>
<th>
Submitted? (Y/N)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Item_RM_Code)
</td>
<td>
@Html.DisplayFor(modelItem => item.Amt_Taken)
</td>
<td>
@if (item.Submitted_ == true)
{
<label class="lbl-yes">Yes</label>
}
else
{
<label class="lbl-no">No</label>
}
</td>
<td>
@Html.ActionLink("Generate List", "GetTotals", new { not sure what to put here yet }) |
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
</div>
对于我的控制器来说,我还没有太多代码,因为我完全被难住了。
public ActionResult Index()
{
var usage = from u in db.InventoryUsage
select u;
return View(usage.Where(u => u.Submitted_ == false).ToList());
}
public ActionResult GetTotals()
{
var list = db.InventoryUsage.Where(x => x.Submitted == false).ToList();
//Stuck on this part//
}
任何建议或指导将不胜感激!
答:
使用并求和结果:GroupBy
IEnumerable<InventoryUsage> usages = ...;
var aggregatedUsages = usages.GroupBy( iu => iu.Item_Code )
.Select( g => new
{
Item_Code = g.Key,
Amt_Taken = g.Select( iu => Convert.ToInt32( iu.Amt_Taken ) )
.Sum();
} );
您没有指定如何处理相同 的值不匹配。如果您希望按项目代码和已提交/未提交值对金额进行总和,则可以将该部分作为密钥的一部分:Submitted
Item_Code
GroupBy
usages.GroupBy( iu => new { iu.Item_Code, iu.Submitted } )
然后投影这些属性:
.Select( g => new
{
Item_Code = g.Key.Item_Code,
Submitted = g.Key.Submitted,
Amt_Taken = ...,
} )
评论
Convert.ToInt32( iu.Amt_Taken )
-- 这使用本地化解析。由于使用的区域设置是服务器的区域设置,而不是客户端的区域设置,因此可能不合适。Querent 真的应该重新考虑他们的数据库设计,以避免这种陷阱。
IGrouping<TKey,TElement>。键
。
2[System.Linq.IGrouping
我终于能够让它工作。@dbc和@Moho,非常感谢你们俩!你为我指明了正确的方向,在研究了更多关于分组方法的东西之后,我最终只是对你的所有建议做了一些小的调整。出于某种原因,它不允许我对我的数据库实体模型执行此操作,因为它使用泛型列表,因此我创建了另一个名为 UsageTotalsModel 的模型类,并仅添加了 InventoryUsage 模型中的相关字段。我猜,由于这不是数据库实体模型,因此它可以使用此函数使用的泛型列表。这是我添加的新模型:
public class UsageTotalsModel
{
public UsageTotalsModel() { }
public string Item_Code { get; set; }
[DisplayFormat(DataFormatString = "{0:0.###}")]
public Nullable<decimal> Amt_Taken { get; set; }
public string UnitOfMeasure { get; set; }
public Nullable<bool> Submitted { get; set; }
public InventoryUsage Usage { set; get; }
}
因此,在我的控制器中,我只是从 InventoryUsage 中提取数据并将其添加到 UsageTotalsModel。这修复了我不断收到的错误消息。
public ActionResult GetTotals()
{
var usage = from u in db.InventoryUsage
where u.Submitted == false
group u by u.Item_Code into g
orderby g.Key
select new UsageTotalsModel() { Item_Code = g.Key, Amt_Taken = g.Sum(u => u.Amt_Taken) };
var result = usage.ToList();
return new ViewAsPdf("GetTotals", result) { PageOrientation = Rotativa.Options.Orientation.Portrait };
}
现在我唯一的问题是带有小数点的项目会自动四舍五入到最接近的十分之一,因此在某些金额上,它为 0.02 磅,它显示为 0。但这是一个不同的问题,如果我卡住了,我会针对这个问题发布另一个问题,但我应该能够弄清楚。无论如何,感谢您对此的帮助!我从来没有想过要通过和选择方法进行分组。我在网上找到的东西似乎令人困惑,不确定它是否适用于我,但多亏了你们,你们让它变得有意义!
评论
Amt_Taken
decimal
InventoryUsage
db.InventoryUsage.GroupBy(x => x.Item_Code).Select(g => new { Item_Code = g.Key, Amt_Taken= g.Sum(x => GetValue(x.Amt_Taken)) })