首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过重复寄存器重构循环

通过重复寄存器重构循环
EN

Code Review用户
提问于 2015-03-10 19:08:19
回答 1查看 310关注 0票数 2

我使用NHibernate在表寄存器中搜索数据。它包含货币登记册、收入和结果。有些寄存器是重复的,所以我设法实现了一些属性,我的C#将检查确定的寄存器是否是重复的,并循环其重复,以便将更多的寄存器添加到结果列表中。基本上,重复寄存器将有所有相同的字段,包括PK Id,但日期将因其重复而有所不同。如果是每天,主循环将重复,直到它达到了寄存器的重复结束日期或方法的头中指定的最后日期;否则,如果任何寄存器的重复结束日期等于null,那么它将继续无限循环。下面的代码就像我上面所说的那样,但速度很慢。我需要让它处理得更快,因为它处理和比较这么多日期:

这是我的注册课程:

代码语言:javascript
复制
public class Register
{
    public Register()
    { }

    // This constructor will create a new Register giving an Register Object, and will set the Date of this new Register.
    public Register(Register r, DateTime d)
    {
        this.Id = r.Id;
        this.Description = r.Description;
        this.Value = r.Value;
        this.Date = d;
        this.Type = r.Type;
        this.IsRepetitive = r.IsRepetitive;
        this.IsOnlyOnWeekdays = r.IsOnlyOnWeekdays;
        this.RepetitionType = r.RepetitionType;
        this.RepetitionEndDate = r.RepetitionEndDate;
    }

    public virtual Int32 Id { get; set; }

    public virtual String Description { get; set; }

    public virtual Decimal Value { get; set; }

    /// <summary>
    /// 0 - Revenue
    /// 1 - Expense
    /// </summary>
    public virtual Int32 Type { get; set; }

    public virtual Boolean IsRepetitive { get; set; }

    public virtual Boolean IsOnlyOnWeekdays { get; set; }

    /// <summary>
    /// 0 - Daily repetition.
    /// 1 - Weekly repetition.
    /// 2 - Monthly repetition.
    /// 3 - Annual repetition.
    /// </summary>
    public virtual Int32 RepetitionType { get; set; }

    public virtual DateTime? RepetitionEndDate { get; set; }

    public virtual DateTime Date { get; set; }

    public virtual IList<ExcludedDate> ExcludedDate { get; set; }
}

下面是我处理所有事情的方法:

代码语言:javascript
复制
public IEnumerable<Register> ObtainRegisters(DateTime EndDate)
{
    ICriteria query = session.CreateCriteria(typeof(Register));

    // Get all the registers using NHibernate.
    var Registers = query.List<Register>().Where(r => r.Date <= EndDate);

    var returnList = new List<Register>();

    // Loop on all the registers.
    foreach (var register in Registers)
    {
        // Check if it's repetitive. If it's not, just add to the return list. If it is, run through the repetition logic.
        if (register.IsRepetitive)
        {
            // Checks the repetition type and runs logic according to it.
            #region Add daily registers

            if (register.RepetitionType == 0)
            {
                for (int i = 0; i <= (EndDate - register.Date.Date).TotalDays; i++)
                {
                    // Obtains this loop date.
                    var loopDate = register.Date.AddDays(i);

                    // Check if it's only on weekdays.
                    if (register.IsOnlyOnWeekdays)
                    {
                        if (loopDate.DayOfWeek != DayOfWeek.Saturday && loopDate.DayOfWeek != DayOfWeek.Sunday)
                        {
                            // Adds the repetitive registers only if it's date is not in any Excluded Dates.
                            if (!register.ExcludedDate.Any(d => d.Date.Date == loopDate))
                            {
                                returnList.Add(new Register(register, loopDate));
                            }
                        }
                    }
                    else
                    {
                        // Adds the repetitive registers only if it's date is not in any Excluded Dates.
                        if (!register.ExcludedDate.Any(d => d.Date.Date == loopDate))
                        {
                            returnList.Add(new Register(register, loopDate));
                        }
                    }


                    if (register.RepetitionEndDate.HasValue)
                    {
                        // Checks is the final date is equals to the loop date.
                        if (register.RepetitionEndDate.Value.Date == loopDate)
                        {
                            break;
                        }
                    }
                }
            }

            #endregion

            #region Add weekly registers

            if (register.RepetitionType == 1)
            {
                if (register.RepetitionEndDate.HasValue)
                {
                    // Checks if the repetition end date is greater or equal to the main end date.
                    if (register.RepetitionEndDate.Value.Date > EndDate.Date)
                    {
                        break;
                    }
                }

                for (int i = 0; i <= (EndDate - register.Date.Date).Days; i = i + 7)
                {
                    // Obtains the loop date.
                    var loopDate = register.Date.AddDays(i);

                    // Checks if the loop date is beyond the repetition end date and finishes the loop if it's the case.
                    if (register.RepetitionEndDate.HasValue)
                    {
                        if (loopDate.Date > register.RepetitionEndDate.Value.Date)
                        {
                            break;
                        }
                    }

                    // Finishes the loop if the loop date is greater then the main end date.
                    if (loopDate.Date > EndDate.Date)
                    {
                        break;
                    }


                    // Adds the repetitive registers only if it's date is not in any Excluded Dates.
                    if (!register.ExcludedDate.Any(d => d.Date.Date == loopDate))
                    {
                        returnList.Add(new Register(register, loopDate));
                    }


                    if (register.RepetitionEndDate.HasValue)
                    {
                        // Checks if the repetition end date equals to the loop date. If true, finishes the loop.
                        if (register.RepetitionEndDate.Value.Date == loopDate)
                        {
                            break;
                        }
                    }
                }
            }

            #endregion

            #region Add monthly registers

            if (register.RepetitionType == 2)
            {
                if (register.RepetitionEndDate.HasValue)
                {
                    // Checks if the repetition end date is equal to the main end date. If true, breaks the loop.
                    if (register.RepetitionEndDate.Value.Date == EndDate.Date)
                    {
                        break;
                    }
                }

                // Runs some loop magic.
                for (int i = 0; i <= (EndDate.Year * 12 + EndDate.Month) - (register.Date.Year * 12 + register.Date.Month); i++)
                {
                    // Obtains the loop date.
                    var loopDate = register.Date.AddMonths(i);

                    // Checks if the repetition end date is greater than the loop date. If true, finishes the loop.
                    if (register.RepetitionEndDate.HasValue)
                    {
                        if (loopDate.Date > register.RepetitionEndDate.Value.Date)
                        {
                            break;
                        }
                    }

                    // Finishes the loop if the loop date is greater then the main end date.
                    if (loopDate.Date > EndDate.Date)
                    {
                        break;
                    }


                    // Adds the repetitive registers only if it's date is not in any Excluded Dates.
                    if (!register.ExcludedDate.Any(d => d.Date.Date == loopDate))
                    {
                        returnList.Add(new Register(register, loopDate));
                    }


                    if (register.RepetitionEndDate.HasValue)
                    {
                        // Checks if the repetition end date equals to the loop date. If true, finishes the loop.
                        if (register.RepetitionEndDate.Value.Date == loopDate)
                        {
                            break;
                        }
                    }
                }
            }

            #endregion

            #region Add annual registers

            if (register.RepetitionType == 3)
            {
                if (register.RepetitionEndDate.HasValue)
                {
                    // Checks if the repetition end date is greater than the main end date. If true, breaks the loop.
                    if (register.RepetitionEndDate.Value.Date > EndDate.Date)
                    {
                        break;
                    }
                }

                for (int i = 0; i <= EndDate.Year - register.Date.Year; i++)
                {
                    // Obtains the loop date.
                    var loopDate = register.Date.AddYears(i);

                    // Checks if the loop date is beyond the repetition end date and finishes the loop if it's the case.
                    if (register.RepetitionEndDate.HasValue)
                    {
                        if (loopDate.Date > register.RepetitionEndDate.Value.Date)
                        {
                            break;
                        }
                    }

                    if (loopDate.Date > EndDate.Date)
                    {
                        break;
                    }


                    // Adds the repetitive registers only if it's date is not in any Excluded Dates.
                    if (!register.ExcludedDate.Any(d => d.Date.Date == loopDate))
                    {
                        returnList.Add(new Register(register, loopDate));
                    }


                    if (register.RepetitionEndDate.HasValue)
                    {
                        // Checks if the repetition end date equals to the loop date. If true, finishes the loop.
                        if (register.RepetitionEndDate.Value.Date == loopDate)
                        {
                            break;
                        }
                    }
                }
            }

            #endregion
        }
        else
        {
            // Adds the non-repetitive register to the return list.
            returnList.Add(register);
        }
    }

    return returnList.OrderBy(r => r.Date);
}
EN

回答 1

Code Review用户

发布于 2015-03-10 19:57:55

  • 不要光着身子Int32S为您列举。这就是为什么enum是为了。公共枚举TransactionType {收入,费用};公共虚拟TransactionType类型{ get;set;}公共枚举RepetitionFrequency {每日,每周,每月,每年};公共虚拟RepetitionFrequency RepetitionType { get;set;}
  • 不要为变量名称(Registros)混合语言。要么选择英语,要么选择你的母语并坚持下去。
  • 对类型和成员变量(DayOfWeek)使用相同的标识符是非常令人困惑的,对于嵌套成员(Date)使用相同的标识符也是令人困惑的!
  • 你有很多重复的代码。每当你发现自己写了同样的东西,或者多次写同样的东西时,一定有办法消除重复。
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/83777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档