asp.net c# Linq查询,用于检索列中每个值的总和
本文关键字:检索 net Linq 查询 用于 asp | 更新日期: 2023-09-27 18:12:32
我有以下TrackerReport对象数组:
public class TrackerReport : TrackerMilestone
{
public long Views { get; set; }
public override string ToString()
{
return "Id=" + MilestoneId + " | Name=" + Name + " | Views = " + Views;
}
我也张贴父类更好地解释:
public class TrackerMilestone
{
public int MilestoneId { get; set; }
public int CampaignId { get; set; }
public string Name { get; set; }
public int? SortIndex { get; set; }
public string Url { get; set; }
public bool IsGoal { get; set; }
public bool IsPartialGoal { get; set; }
public int? ParentMilestoneId { get; set; }
public int? ViewPercent { get; set; }
public override string ToString()
{
return "Id=" + MilestoneId + " | Name=" + Name + " | Url = " + Url;
}
}
使它或多或少像这样显示:
ID Name Url Counter
1 A ab.com 5
2 N ac.com 2
我有一个这个对象的列表,我用这种方式填充:
var trackerReportList = new List<TrackerReport[]>();
foreach (var trackerItem in trackerChildren)
{
//currentReport is the array of TrackerReport TrackerReport[] above mentioned
var currentReport = GetReportForItem(GetFromDate(), GetToDate(), trackerItem.ID,
FindCampaignId(trackerItem));
trackerReportList.Add(currentReport);
}
所有的表项都有相同的值,但是计数器,所以,例如:
list1:
ID Name Url Counter
1 A ab.com 5
2 N ac.com 2
用于:
ID Name Url Counter
1 A ab.com 17
2 N ac.com 28
我的目标是生成单个TrackerReport[],将计数器值的总和作为计数器。
TrackerReport []:
ID Name Url Counter
1 A ab.com 22
2 N ac.com 30
是否有任何Linq查询来做到这一点?或者,如果你想出了一个更好的解决方案,就把它贴出来。
提前感谢!
下面是使用Linq的方法。
-
首先,您希望在单个列表中获取数据,而不是
Arrays
的List
。我们可以用SelectMany
来做这件事。trackerReportList.SelectMany(c => c)
压扁List<TrackerReport[]>()
成IEnumerable<TrackerReport>
-
然后按相关列/列对对象进行分组
group p by new { ID = p.MilestoneId, Name = p.Name, Url = p.Url} into g
-
最后,将分组投影成我们想要的格式。
Counter
是由Adding
和Views
对每个分组中的对象集合得到的。select new { ... };
综合来看:
var report = from p in trackerReportList.SelectMany(c => c)
group p by new {
ID = p.MilestoneId,
Name = p.Name,
Url = p.Url} into g
select new {
ID = g.Key.ID,
Name = g.Key.Name,
Url = g.Key.Url,
Counter = g.Sum(c => c.Views)
};
这是您要查询的lambda expression
。
TrackerReport[] trackerInfoList = trackerReportList
.SelectMany(s => s)
.GroupBy(g => g.MilestoneId)
.Select(s =>
{
var trackerReportCloned = Clone<TrackerReport[]>(s.First());
trackerReportCloned.Views = s.Sum(su => su.Views);
return trackerReportCloned;
})
.ToArray();
如果您注意到,我已经使用Clone<T>(T)
方法通过分组值深度克隆一个object
。我本可以通过复制每个属性来完成,但我发现这是最简单的方法。
这是Clone()
方法:
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
在继续之前,您需要在您的DTO
对象上设置[Serializable]
属性。
[Serializable]
public class TrackerReport : TrackerMilestone
{
.
.
.
}
[Serializable]
public class TrackerMilestone
{
.
.
.
}
希望,这就是你要找的。
我会这样做:1)设TrackerReports[] resultList
为trackerReportList[0]
项的深度副本数组2)据我所知,Views属性对应于Counter列。如果是,则
foreach(report in resultList)
{
report.Views = trackerReportList.Sum(reports => reports.Single(r => r.MilestoneId == report.MilestoneId).Views);
}