我用asp.net mvc 3.情况:
我有模型类“事件”
public class Event
{
public string Name { get; set; }
public Period Plan { get; set; }
public Period Fact { get; set; }
}
public class Period
{
public bool isPeriod { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
}
和控制器中的 ActionResult 方法“示例”。在这种方法中,我有 list<Event> 集合,我需要从 list<Event> 获取字典<DateTime, int>。DateTime - 某个日期,int - 此日期的事件数。事件可以持续几天(isPeriod=1)或仅持续一天(isPeriod=0)。事件的日期也有一些限制,应该添加(dateFrom,dateTo)。
我写了一些代码,适用于这种情况,但看起来不太好。代码的某些部分重复了很多次。可以做些什么来优化这部分代码?也许这里可以使用 LINQ 或其他东西以更简单的方式获得结果?
public ActionResult Example()
{
List<Event> events = new List<Event>();
...
Dictionary<DateTime, int> days = new Dictionary<DateTime, int>(); //Dictionary which I need in result
Dictionary<DateTime, HashSet<string>> dic = new Dictionary<DateTime, HashSet<string>>(); //this dictionary is used in foreach cycle
foreach (var ev in events)
{
//plan
//exact date
if (!ev.Plan.isPeriod)
{
if (ev.Plan.From >= dateFrom && ev.Plan.From <= dateTo)
{
if (!dic.ContainsKey(ev.Plan.From))
{
dic.Add(ev.Plan.From, new HashSet<string>());
dic[ev.Plan.From].Add(ev.Key.ToString());
}
else
{
dic[ev.Plan.From].Add(ev.Key.ToString());
}
}
}
//period
else
{
//period is between dateFrom and dateTo
if (ev.Plan.From >= dateFrom && ev.Plan.To <= dateTo)
{
for (DateTime date = ev.Plan.From; date <= ev.Plan.To; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
//period begins before dateFrom
else if (ev.Plan.From < dateFrom && ev.Plan.To <= dateTo)
{
for (DateTime date = dateFrom; date <= ev.Plan.To; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
//period ends after dateTo
else if (ev.Plan.From >= dateFrom && ev.Plan.To > dateTo)
{
for (DateTime date = ev.Plan.From; date <= dateTo; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
}
//fact
//exact date
if (!ev.Fact.isPeriod)
{
if (ev.Fact.From >= dateFrom && ev.Fact.From <= dateTo)
{
if (!dic.ContainsKey(ev.Fact.From))
{
dic.Add(ev.Fact.From, new HashSet<string>());
dic[ev.Fact.From].Add(ev.Key.ToString());
}
else
{
dic[ev.Fact.From].Add(ev.Key.ToString());
}
}
}
//period
else
{
//period is between dateFrom and dateTo
if (ev.Fact.From >= dateFrom && ev.Fact.To <= dateTo)
{
for (DateTime date = ev.Fact.From; date <= ev.Fact.To; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
//period begins before dateFrom
else if (ev.Fact.From < dateFrom && ev.Fact.To <= dateTo)
{
for (DateTime date = dateFrom; date <= ev.Fact.To; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
//period ends after dateTo
else if (ev.Fact.From >= dateFrom && ev.Fact.To > dateTo)
{
for (DateTime date = ev.Fact.From; date <= dateTo; date = date.AddDays(1.0))
{
if (!dic.ContainsKey(date))
{
dic.Add(date, new HashSet<string>());
dic[date].Add(ev.Key.ToString());
}
else
{
dic[date].Add(ev.Key.ToString());
}
}
}
}
//getting result Dictionary
foreach (var d in dic)
{
days.EventsCount[d.Key] = d.Value.Count();
}
}
return View(days);
}