用嵌套字典编写这样一个条目的最佳、更实用的方法是啥?使用哪种设计模式? C#

Posted

技术标签:

【中文标题】用嵌套字典编写这样一个条目的最佳、更实用的方法是啥?使用哪种设计模式? C#【英文标题】:What is the best, more practical way to write such an entry with nested dictionaries? Which design pattern to use? C#用嵌套字典编写这样一个条目的最佳、更实用的方法是什么?使用哪种设计模式? C# 【发布时间】:2022-01-16 17:25:10 【问题描述】:

数据库中有大量数据,需要使用c#集合来产生统计数据(求应用程序的每个用户每天的平均操作次数)。在我看来,有必要使用字典:

var dict = new Dictionary<long?, Dictionary<DateTime, Dictionary<OperationsGroupType, int>>>();

请提供更实用的编写方法。因为它看起来很奇怪。谢谢

我写了一个函数:

public void D()
        
            var dict = new Dictionary<long?, Dictionary<DateTime, Dictionary<OperationsGroupType, int>>>();
            int pageNumber = 0;
            int pageSize = 5;
            int pageCount = 1;

            while (pageNumber < pageCount)
            
                int count;
                foreach (OperationData op in OperationService.GetPage(pageNumber, pageSize, out count))
                    if(op.PerformedBy.HasValue)
                        if(op.PerformedDate.HasValue)
                            if (dict.ContainsKey(op.PerformedBy))
                                if (dict[op.PerformedBy].ContainsKey(op.PerformedDate.Value.Date.Date))
                                    if (dict[op.PerformedBy][op.PerformedDate.Value.Date.Date.Date.Date].ContainsKey(op.Type)) dict[op.PerformedBy][op.PerformedDate.Value.Date.Date.Date.Date][op.Type]++;
                                    else dict[op.PerformedBy][op.PerformedDate.Value.Date.Date.Date.Date].Add(op.Type, 1);
                                else dict[op.PerformedBy].Add(op.PerformedDate.Value.Date.Date.Date.Date, new Dictionary<OperationsGroupType, int>   op.Type, 1  );
                            else dict.Add(op.PerformedBy, new Dictionary<DateTime, Dictionary<OperationsGroupType, int>>   op.PerformedDate.Value.Date.Date.Date.Date, new Dictionary<OperationsGroupType, int>   op.Type, 1    );

                pageCount = (count - 1) / pageSize + 1;
                pageNumber++;
            

            foreach (var item in dict)
            
                var opDateDict = new Dictionary<DateTime, int>();
                foreach (var operDate in item.Value) opDateDict.Add(operDate.Key, operDate.Value.Sum(count => count.Value));

                SystemLogger.Instance.WriteErrorTrace(String.Format("Average number of user operations 0 per day: 1\n", item.Key, opDateDict.Values.Sum() / opDateDict.Count));
            
        
OperationsGroupType - this enum

请告诉我如何用更实用的设计替换字典? 哪种模式最适合解决这个问题?

【问题讨论】:

“数据库中的数据很多,需要做统计”——所以用数据库来做点什么,主要是聚合大数据集!不要将所有数据都拉到 C# 代码中。 不要使用嵌套集合。他们很少像你说的那样很好地记录你在做什么,看起来很奇怪! 我完全同意米奇的观点。使用 SQL 获取聚合和计算。 感谢您的回答,但目前我需要使用收藏。因为 SQL 应用太早了 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。 【参考方案1】:

很难说什么是最好的或最实用的——那是因为你没有真正定义“最好”或“实用”的含义。

我将它们定义为最少的代码和最少的重复。

首先我创建了这些扩展方法:

public static class Ex

    public static R Ensure<T, R>(this Dictionary<T, R> @this, T key) where R : new
    
        if (@this.ContainsKey(key))
            return @this[key];
        else
        
            var r = new R();
            @this[key] = r;
            return r;
        
    

    public static R Ensure<T, R>(this Dictionary<T, R> @this, T key, Func<R> factory)
    
        if (@this.ContainsKey(key))
            return @this[key];
        else
        
            var r = factory();
            @this[key] = r;
            return r;
        
    

有了这些,我可以像这样重写你的代码:

foreach (OperationData op in OperationService.GetPage(pageNumber, pageSize, out count))

    if (op.PerformedBy.HasValue)
        if (op.PerformedDate.HasValue)
        
            dict.Ensure(op.PerformedBy).Ensure(op.PerformedDate.Value.Date).Ensure(op.Type, () => 0);
            dict[op.PerformedBy][op.PerformedDate.Value.Date][op.Type]++;
        

【讨论】:

以上是关于用嵌套字典编写这样一个条目的最佳、更实用的方法是啥?使用哪种设计模式? C#的主要内容,如果未能解决你的问题,请参考以下文章

用pydantic指定嵌套字典的最佳方法?

在没有 NoneType 错误的情况下访问嵌套字典的 pythonic 方法是啥

用 setState() 更新嵌套的 React 状态属性的最佳选择是啥?

解析服务器:用远程数据更新本地存储的最佳方法是啥

将默认dict更改为嵌套字典

为 ASP.NET 编写月份和年份下拉列表的最佳方法是啥?