Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have method which checks period and return schedules:

public IEnumerable<EventSchedule> GetSchedulesForPeriod(PeriodEvent period, string tab = "")
        {
            switch (period)
            {
                case PeriodEvent.Today:
                    return GetTodaySchedules(tab);

                case PeriodEvent.Tomorrow:
                    return GetTomorrowSchedules(tab);

                case PeriodEvent.Week:
                    return GetWeekSchedules(tab);

                case PeriodEvent.FewWeek:
                    return GetFewWeekSchedules(tab);

                case PeriodEvent.Month:
                    return GetMonthSchedules(tab);
                case PeriodEvent.All:
                    return GetAllFromTodaySchedules(tab);

                default:
                    return GetTodaySchedules(tab);
            }
        }

Consider the GetTodaySchedules and GetTomorrowSchedules:

    private IEnumerable<EventSchedule> GetTodaySchedules(string tab)
{
    var today = DateTime.Now.Date;

    var result = Database.EventSchedules.Where(s => s.RecurrenceStart.Value.Date <= today &&
         s.RecurrenceEnd.Value.Date >= today &&
         s.BaseEvent.IsApproved.Value && !s.IsRemoved.Value &&
         s.BaseEvent.EventsCategories.Any(
         c => c.EventCategory.Name == tab)).ToList();

    return result.Where(s => Evaluator.CheckDate(s, today)).ToList();
} 
private IEnumerable<EventSchedule> GetTomorrowSchedules(string tab)
{
    var today = DateTime.Now.AddDays(1).Date;
    var result = Database.EventSchedules.Where(s => s.RecurrenceStart.Value.Date <= today &&
         s.RecurrenceEnd.Value.Date >= today &&
         s.BaseEvent.IsApproved.Value && !s.IsRemoved.Value &&
         s.BaseEvent.EventsCategories.Any(
         c => c.EventCategory.Name == tab)).ToList();

    return result.Where(s => Evaluator.CheckDate(s, today)).ToList();
}

The similar code have all methods above. How to rewrite it? May be, there is some pattern for this? And, the second, now I want that tab checks only if it filled and introduce new var called placeName (also check if filled):

private IEnumerable<EventSchedule> GetTodaySchedules(string tab, string placeName)
    {
        var today = DateTime.Now.Date;

        var result = Database.EventSchedules.Where(s => s.RecurrenceStart.Value.Date <= today &&
             s.RecurrenceEnd.Value.Date >= today &&
             s.BaseEvent.IsApproved.Value && !s.IsRemoved.Value &&
             s.BaseEvent.EventsCategories.Any(
             c => c.EventCategory.Name == tab) && s.BasePlace.Name).ToList();

        return result.Where(s => Evaluator.CheckDate(s, today)).ToList();
    } 

I don't want to create separate methods for this. What is best way to do this?

Thanks.

share|improve this question
add comment

2 Answers 2

up vote 3 down vote accepted

You can compose query predicates by applying several where clauses in a row. The predicates must be passed as Expression<Func<T, bool>> for composition.

See LINQ to Entities: Combining Predicates on blogs.msdn.com.

Create a general schedules query like this

private IEnumerable<EventSchedule> GetSchedules(
    string tab,
    Expression<Func<EventSchedule, bool>> dateCondition)
{ 
    var result = Database.EventSchedules
        .Where(s => s.BaseEvent.IsApproved.Value &&
            !s.IsRemoved.Value &&
            s.BaseEvent.EventsCategories.Any(c => c.EventCategory.Name == tab))
        .Where(dateCondition)
        .ToList();
    return result.Where(s => Evaluator.CheckDate(s, today)).ToList();
}

And then pass it the appropriate individual date predicate like this

private IEnumerable<EventSchedule> GetTodaySchedules(string tab) {
    var today = DateTime.Now.Date;
    return GetSchedules(
        tab,
        s => s.RecurrenceStart.Value.Date <= today &&
             s.RecurrenceEnd.Value.Date >= today);
}

private IEnumerable<EventSchedule> GetTomorrowSchedules(string tab) {
    var tomorrow = DateTime.Now.AddDays(1).Date;
    return GetSchedules(
        tab,
        s => s.RecurrenceStart.Value.Date <= tomorrow &&
             s.RecurrenceEnd.Value.Date >= tomorrow);
}
share|improve this answer
add comment

Just add another argument to the method:

private IEnumerable<EventSchedule> GetSchedules(string tab, DateTime day)
{
    var result = Database.EventSchedules.Where(s => s.RecurrenceStart.Value.Date <= day &&
         s.RecurrenceEnd.Value.Date >= day &&
         s.BaseEvent.IsApproved.Value && !s.IsRemoved.Value &&
         s.BaseEvent.EventsCategories.Any(
             c => c.EventCategory.Name == tab)).ToList();

    return result.Where(s => Evaluator.CheckDate(s, day)).ToList();
}

And call it with an appropriate value for day. Easy, no?

share|improve this answer
    
Additionally properties can be made to get the appropriate days. Today returns DateTime.Today.Date, Tomorrow returns DateTime.Tomorrow.AddDays(1).Date, etc. Though I'd make the day parameter first. That way calls to the method could look like: GetSchedules(Today, tab) –  Jeff Mercado Apr 26 '12 at 14:04
    
There is more complex queries( RecurrenceStart and RecurrenceEnd) –  user348173 Apr 26 '12 at 15:49
    
@user348173 Well you didn’t show them. But doesn’t matter, the same principle can be applied: just provide the parts that vary as arguments to the method. –  Konrad Rudolph Apr 26 '12 at 16:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.