C#中的LINQ查询的简化版本

时间:2019-01-21 18:11:31

标签: c# asp.net .net c#-4.0

我有一个函数,它接受两个日期,即fromdate和todate以及一个时区(UTC和IST)。

基于这些,我需要过滤一个对象列表,该对象列表的FromDate和ToDate之间有一个名为“ StartDate”的字段。

public void CheckDate(ref List<CustomObj> cObj,DateTime fromdate, DateTime toDate,object timeZone)
{

 cObj = cObj.where( x => 
 {

  bool result = false;
  switch(timeZone)
  {
    case "UTC" :
                var utc = Convert.ToDateTime(x.StartDate);
                if(fromDate <= utc && utc <= toDate)
                {
                  result = true;
                }
                else
                {
                  result = false;
                }
                break;
    case "IST" :
              {
               // Similar logic but convert to IST and check
              }
              break;
         }
      }
   }

此函数工作正常,但是有什么办法可以通过编写简化的LINQ查询来简化此过程,而不是在lambda的where子句中编写太多逻辑来简化它?

4 个答案:

答案 0 :(得分:1)

你得到的还不错。逻辑具有分支,因此您必须分支。

我们仍然可以减少一些事情,并提供单独的可重用逻辑:

public void CheckDate (List<CustomObj> cObj, DateTime fromdate, DateTime toDate, object timeZone) {
    cObj = cObj.where (x => {
        var recordStartDate = ConvertDate (timeZone, x.StartDate);
        return recordStartDate.HasValue && // Your choice whether you want to exclude null
            fromDate <= recordStartDate.Value && recordStartDate.Value <= toDate;
    });
}

public static DateTime? ConvertDate (string timeZone, DateTime sourceDate) {
    switch (timeZone) {
        case "utc":
            return Convert.ToDateTime (sourceDate);
        case "ist":
            return sourceDate; // IST logic here
        default:
            return null;
    }
}

答案 1 :(得分:1)

如果仅支持两个时区,则三元运算符可能就足够了。您可以检查它是否为IST,否则默认为UTC。

    public void CheckDate(ref List<CustomObj> cObj, DateTime fromDate, DateTime toDate, string timeZone)
    {
        cObj = cObj.Where(x =>
        {
            var date = timeZone == "IST" ? /*convert to IST*/ : Convert.ToDateTime(x.StartDate);
            return fromDate <= date && date <= toDate;
        }).ToList();
    }

答案 2 :(得分:0)

通常最好将所有日期以相同的格式/时区存储(将所有日期存储为UTC),这将使您的生活更加轻松。但是,如果您依赖集合中的项目作为条件,您将无法简化很多工作。

@Meligy的答案的替代品,而不是LINQ,也许您应该只使用传统的foreach循环?

    public bool CheckDate(List<CustomObj> cObj, DateTime fromdate, DateTime toDate, object timeZone)
    {
        bool result = false;
        DateTime date;

        foreach(CustomObj obj in cObj)
        {
            date = DateTime.MinValue;
            switch (timeZone)
            {
                case "UTC":
                    date = Convert.ToDateTime(obj.StartDate);
                    break;
                case "IST":
                    // stuff
                    break;
            }

            if (date >= fromdate && date <= toDate)
            {
                result = true;
                break;
            }
        }

        return result;
    }

答案 3 :(得分:0)

您可能可以做类似的事情

        public int CheckDate(ref List<dates> cObj, DateTime fromdate, DateTime toDate, string timeZone)
        {
            var currentZone = TimeZoneInfo.FindSystemTimeZoneById(timeZone);

            var result = (from obj in cObj
                         let currdTime = TimeZoneInfo.ConvertTime(obj.StartDate, currentZone)
                         where fromdate <= currdTime && toDate >= currdTime
                         select obj).ToList();

            return result.Count() > 0 ? 1 : 0;
        }

您可以使用内置的时区类及其标准名称,并将时间转换为所需的时区并进行比较。也许您可以抓取并创建所有标准时区的自定义Enumeration类,因此将来在包含时区时,不必更改代码。该代码未经测试,但我希望它能使您对如何实现输出有所了解。