views:

1793

answers:

3

I was wondering if anyone had a better idea how to do this. atm returning IQueryable<Member> as ObjectQuery<Member> seems dirty to me.

namespace Falcon.Business.Repositories
{
    using System;
    using System.Data.Objects;
    using System.Linq;
    using Falcon.Business.Criteria;
    using Falcon.Business.Entities;
    using Falcon.Business.Enums;
    using Falcon.Business.Extensions;
    using Falcon.Business.Repositories.Interfaces;
    using Falcon.Business.Services;
    using Falcon.Business.Services.Interfaces;
    using Falcon.Core.Extensions;

    public class MemberRepository : LinqRepository<Member>, IMemberRepository
    {
     public Member Fetch(MemberCriteria criteria)
     {
      ObjectQuery<Member> query = base.CreateQuery();

      query = this.AddRelations(query);
      query = this.AddCriteria(query, criteria);
      query = this.AddCriteriaOrder(query, criteria);

      return query.FirstOrDefault();
     }

     public IPagerService<Member> FetchAll(MemberCriteria criteria)
     {
      int page = (criteria.Page.HasValue) ? criteria.Page.Value : 1;
      int limit = criteria.Limit;
      int start = (page * limit) - limit;
      int total = this.Count(criteria);

      ObjectQuery<Member> query = base.CreateQuery();

      query = this.AddRelations(query);
      query = this.AddCriteria(query, criteria);
      query = this.AddCriteriaOrder(query, criteria);

      return new PagerService<Member>(query.Skip(start).Take(limit).ToList(), page, limit, total);
     }

     public int Count(MemberCriteria criteria)
     {
      ObjectQuery<Member> query = base.CreateQuery();

      query = this.AddCriteria(query, criteria);

      return query.Count();
     }

     public ObjectQuery<Member> AddCriteria(IQueryable<Member> query, MemberCriteria criteria)
     {
      if (criteria.Title.HasValue())
      {
       query = query.Where(q => q.Title == criteria.Title);
      }

      if (criteria.TitleUrl.HasValue())
      {
       query = query.Where(q => q.TitleUrl == criteria.TitleUrl);
      }

      if (criteria.EmailAddress.HasValue())
      {
       query = query.Where(q => q.EmailAddress == criteria.EmailAddress);
      }

      if (criteria.HostAddress.HasValue())
      {
       query = query.Where(q => q.HostAddress == criteria.HostAddress);
      }

      query = query.Where(q => q.Status == criteria.Status);

      return query as ObjectQuery<Member>;
     }

     public ObjectQuery<Member> AddCriteriaOrder(IQueryable<Member> query, MemberCriteria criteria)
     {
      if (criteria.Sort == SortMember.ID)
      {
       query = criteria.Order == SortOrder.Asc
                 ? query.OrderBy(q => q.ID)
                 : query.OrderByDescending(q => q.ID);
      }
      else if (criteria.Sort == SortMember.Posts)
      {
       query = criteria.Order == SortOrder.Asc
        ? query.OrderBy(q => q.Posts)
        : query.OrderByDescending(q => q.Posts);
      }
      else if (criteria.Sort == SortMember.Title)
      {
       query = criteria.Order == SortOrder.Asc
        ? query.OrderBy(q => q.Title)
        : query.OrderByDescending(q => q.Title);
      }
      else if (criteria.Sort == SortMember.LastLogin)
      {
       query = criteria.Order == SortOrder.Asc
        ? query.OrderBy(q => q.LastLogin)
        : query.OrderByDescending(q => q.LastLogin);
      }
      else if (criteria.Sort == SortMember.LastVisit)
      {
       query = criteria.Order == SortOrder.Asc
        ? query.OrderBy(q => q.LastVisit)
        : query.OrderByDescending(q => q.LastVisit);
      }
      else
      {
       query = criteria.Order == SortOrder.Asc
        ? query.OrderBy(q => q.Created)
        : query.OrderByDescending(q => q.Created);
      }

      return query as ObjectQuery<Member>;
     }

     private ObjectQuery<Member> AddRelations(ObjectQuery<Member> query)
     {
      query = query.Include(x => x.Country);
      query = query.Include(x => x.TimeZone);
      query = query.Include(x => x.Profile);

      return query;
     }
    }
}
A: 

I also do not like returning an objectquery, because doing so will make you very dependent on Entity Framwork. Knowing Microsoft they propably make a lot of changes in version 2, so you do not want to do this.

NHibernate uses criteria, a bit like you suggested, but their implementation is a lot more generic. I like the more generic implementation more then you example because then you do not need to build criteria for every object. On the other hand, you implementation is typed, which is also very neat. If you want the best of both, a more generic implementation that is typed, you might want to take a look at the NHibernate implementation but instead of using strings, use lambda functions and .Net generics. I could post an example how to do this, but I'm currently not on my own machine.

A: 

I have used nhibernate before in the past and the linq to nhibernate still has a bit to go, btw The AddCriteria and AddCriteriaOrder are never exposed on the interface they are specific to that repository class.

Mike Geise
This should be a comment to Henk's post, not a separate answer.
sth
are you really that ignorant to dig up a old question like this to post a comment like that?
Mike Geise
A: 

I was wondering if you have a full example of this criteria search you made with Entity Framework, coz i tried to follow you and made some examples but i get stuck in the relationship part.

Thanks

Manuel.