2009-05-09 9 views
3

Как реализовать шаблон спецификации для запроса базы данных с помощью NHibernate? (Без LINQ to NHibernate). Я много читал о шаблоне спецификации, но большинство из них касалось объектов сбора и проверки объектов памяти.Шаблон спецификации для запроса к базе данных с использованием NHibernate

Лучший способ, насколько я знаю, используя DetachedCriteria в спецификации интерфейса, как это.

interface ISpecification<T> { 

bool IsSatisfiedBy(T object); 

DetachedCriteria CreateCriteria(); 

} 

Есть ли альтернатива или лучший способ сделать это?

+0

Я исследовал подобную тему и нашел их сообщения интересные: [Реализация спецификации шаблона] (http://colinjack.blogspot.co m/2007/06/specification-pattern-implementation.html) и [Extensible Query with Specification Pattern] (http://hendryluk.wordpress.com/2009/03/23/extensible-query-with-specification-patterns/) – Marijn

ответ

3

Это не nessary лучше, но может быть альтернативный

interface ISpecification<T> 
{ 
    bool IsSatisfiedBy(T object); 

    Expression<Func<T, bool>> Predicate { get; } 
} 

Легко использовать более LINQ (для NHibernate) и память-коллекции.

+0

Как я могу использовать эту базу данных? Можете ли вы привести мне пример? – mcaaltuntas

+0

return MyISession.Linq () .Where (спецификация. Prefix) .ToList() – Paco

+0

Я действительно не использую его так просто в своем коде, но я использую объект запроса, чтобы добавить поддержку для активной загрузки, упорядочения, и т. д. – Paco

0

Я реализовал это с использованием простого метода расширения и спецификации, работает для списков System.Linq.IQueryable.

public interface IFilter<in T> 
{ 
    bool MatchFilter(T o); 
} 

public static class FilterExtension 
{ 
    public static IQueryable<T> Filter<T>(this IQueryable<T> query, IFilter<T> filter) 
    { 
     return query.Where(x => filter.MatchFilter(x)); 
    } 
} 

Простые примеры классов и реализация IFilter:

public class Organization 
{ 
    public string Name { get; set; } 
    public string Code { get; set; } 
    public Address Address { get; set; } 


    public Organization(string name, string code, string city, string country) 
    { 
     Name = name; 
     Code = code; 
     Address = new Address(city, country); 
    } 

} 

public class Address 
{ 
    public Address(string city, string country) 
    { 
     City = city; 
     Country = country; 
    } 

    public string City { get; set; } 
    public string Country { get; set; } 
} 

public class GenericOrganizationFilter : IFilter<Organization> 
{ 
    public string FilterString { get; set; } 

    public GenericOrganizationFilter(string filterString) 
    { 
     FilterString = filterString; 
    } 

    public bool MatchFilter(Organization o) 
    { 
     return 
      (o.Name != null && o.Name.Contains(FilterString)) || 
      (o.Code != null && o.Code.Contains(FilterString)) || 
      (o.Address != null && o.Address.City != null && o.Address.City.Contains(FilterString)) || 
      (o.Address != null && o.Address.Country != null && o.Address.Country.Contains(FilterString)); 
    } 
} 

Использование:

IFilter<Organization> filter = new GenericOrganizationFilter("search string"); 
//Assuming queryable is an instance of IQueryable<Organization>. 
IQueryable<Organization> filtered = queryable.Filter(filter);