我如何组织这些数据转化为我想和LINQ的对象?(How can I organize this da

2019-09-17 12:19发布

我有一个下面的类我试图创建的列表,一组数据我质疑:

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()或类似的东西的情况下? 我那种丢在这里。

Answer 1:

我希望这样做的工作。

// 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)
            })
      });

顺便说一句,想想使用十进制或浮动的平均时间。



Answer 2:

编辑:我想我个人比较喜欢丹尼尔的解决方案在简单性方面,虽然我的会更有效(因为它并不需要通过多次调用来评估查询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);
        }
    }
}


文章来源: How can I organize this data into the objects I want with LINQ?