2008-12-04 11 views
2

Мне было интересно, если кто-нибудь лучше подумал, как это сделать. atm возвращение IQueryable<Member> как ObjectQuery<Member> кажется грязным для меня.Entity Framework, строительный запрос на основе критериев

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; 
     } 
    } 
} 
+1

Хех, и это должно быть улучшение по сравнению с T-SQL! Иди сюда :) Просто шучу. – RobS 2009-02-25 08:40:07

ответ

2

Мне также не нравится возвращать объектную заявку, потому что это сделает вас очень зависимыми от Entity Framwork. Зная Microsoft, они, возможно, вносят много изменений в версию 2, поэтому вы не хотите этого делать.

NHibernate использует критерии, похожие на предложенные вами, но их реализация намного более общая. Мне больше нравится более общая реализация, чем пример, потому что тогда вам не нужно создавать критерии для каждого объекта. С другой стороны, вы вводите типизацию, которая также очень аккуратная. Если вы хотите получить лучшее из того и другого, более типичную реализацию, которая набирается, вы можете взглянуть на реализацию NHibernate, но вместо того, чтобы использовать строки, используйте лямбда-функции и .Net-генераторы. Я мог бы привести пример, как это сделать, но сейчас я не на своей машине.