Pregunta

¿Cómo se implementa el patrón de especificación para consultar la base de datos utilizando NHibernate? (sin LINQ to NHibernate). Leí mucho sobre el patrón de especificación, pero la mayoría de ellos se referían a objetos de recopilación de validación y consulta de memoria.

El mejor método, que yo sepa, utilizando DetachedCriteria en la interfaz de especificación como esta.

interface ISpecification<T> {

 bool IsSatisfiedBy(T object);

 DetachedCriteria CreateCriteria();

}

¿Hay alguna forma alternativa o mejor de hacer esto?

¿Fue útil?

Solución

Esto no es necesariamente mejor, pero puede ser una alternativa

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

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

Fácil de usar sobre linq (para inhibir) y colecciones de memoria.

Otros consejos

Implementé esto usando un método de extensión simple y un patrón de especificación, funciona para las listas 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));
    }
}

Clases de ejemplo simples e implementación de 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));
    }
}

Uso:

IFilter<Organization> filter = new GenericOrganizationFilter("search string");
//Assuming queryable is an instance of IQueryable<Organization>. 
IQueryable<Organization> filtered = queryable.Filter(filter);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top