我有一个下面的类我试图创建的列表,一组数据我质疑:
public class Agency
{
public string AgencyName { get; set; }
public int AgencyID { get; set; }
public IEnumerable<AuditRule> rules { get; set; }
}
其中,“AuditRule”是:
public class AuditRule
{
public int AuditRuleID { get; set; }
public string AuditRuleName { get; set }
public int AvgDaysWorked { get; set; }
}
眼下,一个相当复杂的查询后,我已经能够让我的数据转换成一个匿名对象,看起来像:
{ DateImported, AgencyID, AgencyName, AuditRuleName, AuditRuleID, DaysWorked }
我有成千上万的记录,在该格式,我试图构建一个的IEnumerable <Agency
>将本身含有的,每家机构的规则列表。
因此,采取以下数据为例:
{ AgencyID = 1, AgencyName = "CCR", AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 3 }
{ AgencyID = 1, AgencyName = "CCR", AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 5 }
{ AgencyID = 1, AgencyName = "CCR", AuditRuleName = "Time", AuditRuleID = 2, DaysWorked = 2 }
{ AgencyID = 2, AgencyName = "YRX", AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 3 }
{ AgencyID = 2, AgencyName = "YRX", AuditRuleName = "Acct", AuditRuleID = 3, DaysWorked = 2 }
所以,出这个数据,我想首先要建立机构名单(类在顶部),这显然是“CCR”和“YRX”这个例子。 然后,对每个机构我想其每个在其IEnumerable的规则条目<AuditRule
>有一个记录。
因此,机构“CCR”必须有2个规则条目,“呼叫”和“时间”。 “呼叫” AuditRule项将成为四AvgDaysWorked因为我们平均为“呼叫”专署“CCR”的为3天至5天工作的条目。 时间AuditRule条目将具有2 AvgDaysWorked,因为只有一个条目。
有人用一些LINQ忍者技能可以帮我这个缠斗数据转换成每个机构机构和规则的列表(天的平均工作了这条规则/机构组合)?
它是复杂的足以让我甚至能够走到一起是匿名对象,我真的很努力写此查询来创建机构/ AuditRules名单。
这是我会用的SelectMany()或类似的东西的情况下? 我那种丢在这里。
我希望这样做的工作。
// GetAnonymousCollection() is hard to define... ;)
var anonymous = GetAnonymousCollection();
IEnumerable<Agency> result = anonymous
.GroupBy(a => a.AgencyID)
.Select(ag => new Agency()
{
AgencyID = ag.Key,
AgencyName = ag.First().AgencyName,
Rules = ag
.GroupBy(agr => agr.AudiRuleID)
.Select(agrg => new AuditRule()
{
AuditRuleID = agrg.Key,
AuditRuleName = agrg.First().AuditRuleName,
AvgDaysWorked = (Int32)agrg.Average(agrgr => agrgr.DaysWorked)
})
});
顺便说一句,想想使用十进制或浮动的平均时间。
编辑:我想我个人比较喜欢丹尼尔的解决方案在简单性方面,虽然我的会更有效(因为它并不需要通过多次调用来评估查询First()
来获取代理/审核规则名称)。 我不完全知道该怎么在这里我的回答做的事:它显示了不同的东西(按组合键分组),这是很好的,但同时它的代码庞大且笨重位。 话又说回来,这是一个完整的例子,这使得它更容易玩...
思想,任何人吗? 我应该在这里离开这个或删除吗?
好吧,我想这你想要做什么。 这是非常邪恶的,但。 我没有时间立即解释,但GroupBy
方法是关键之一。
我已经格式化了一点,但它仍然不理想......
using System;
using System.Collections.Generic;
using System.Linq;
public class Agency
{
public string AgencyName { get; set; }
public int AgencyID { get; set; }
public IEnumerable<AuditRule> Rules { get; set; }
public override string ToString()
{
return string.Format("Agency {0}/{1}:\r\n{2}",
AgencyID, AgencyName,
string.Concat(Rules.Select(x => x.ToString() + "\r\n")
.ToArray()));
}
}
public class AuditRule
{
public int AuditRuleID { get; set; }
public string AuditRuleName { get; set; }
public int AvgDaysWorked { get; set; }
public override string ToString()
{
return string.Format("Audit rule {0}/{1}: {2}", AuditRuleID,
AuditRuleName, AvgDaysWorked);
}
}
class Test
{
static void Main()
{
var previousQuery = new[]
{
new { AgencyID = 1, AgencyName = "CCR",
AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 3 },
new { AgencyID = 1, AgencyName = "CCR",
AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 5 },
new { AgencyID = 1, AgencyName = "CCR",
AuditRuleName = "Time", AuditRuleID = 2, DaysWorked = 2 },
new { AgencyID = 2, AgencyName = "YRX",
AuditRuleName = "Call", AuditRuleID = 1, DaysWorked = 3 },
new { AgencyID = 2, AgencyName = "YRX",
AuditRuleName = "Acct", AuditRuleID = 3, DaysWorked = 2 },
};
var itemsGroupedByAgency = previousQuery.GroupBy
(item => new { item.AgencyID, item.AgencyName });
// Want to do the query for each group
var query = itemsGroupedByAgency.Select
// Outdented to avoid scrolling
(group => new Agency
{
AgencyName = group.Key.AgencyName,
AgencyID = group.Key.AgencyID,
Rules = group.GroupBy(item => new { item.AuditRuleName,
item.AuditRuleID },
(key, items) => new AuditRule
// Outdented to avoid scrolling :)
{
AuditRuleID = key.AuditRuleID,
AuditRuleName = key.AuditRuleName,
AvgDaysWorked = (int) items.Average(x => x.DaysWorked)
})
});
foreach (var item in query)
{
Console.WriteLine(item);
}
}
}