public interface IRepository<T> : INHibernateQueryable<T>
{
    ITransaction BeginTransaction();
    void Delete(T item);
    T Get(object id);
    void Save(T target);
    void Update(T item);
}
public class NHibernateRepository<T> : IRepository<T>, IDisposable
{
    readonly ISessionManager _sessionManager;
    INHibernateQueryable<T> _queryable;
    ISession _session;
    public NHibernateRepository(ISessionManager sessionManager)
    {
        _sessionManager = sessionManager;
    }
    INHibernateQueryable<T> AsQueryable
    {
        get
        {
            if (_queryable == null)
                _queryable = Session.Linq<T>();
            return _queryable;
        }
    }
    public Type ElementType
    {
        get { return AsQueryable.ElementType; }
    }
    public Expression Expression
    {
        get { return AsQueryable.Expression; }
    }
    public IQueryProvider Provider
    {
        get { return AsQueryable.Provider; }
    }
    public QueryOptions QueryOptions
    {
        get { return AsQueryable.QueryOptions; }
    }
    public ISession Session
    {
        get
        {
            if (_session == null)
                _session = _sessionManager.OpenSession();
            return _session;
        }
    }
    public void Dispose()
    {
        if (_session != null)
            _session.Dispose();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public IEnumerator<T> GetEnumerator()
    {
        return AsQueryable.GetEnumerator();
    }
    public IQueryable<T> Expand(string path)
    {
        return AsQueryable.Expand(path);
    }
    public ITransaction BeginTransaction()
    {
        return Session.BeginTransaction();
    }
    public void Delete(T item)
    {
        Session.Delete(item);
    }
    public T Get(object id)
    {
        return Session.Get<T>(id);
    }
    public void Save(T target)
    {
        Session.SaveOrUpdate(target);
    }
    public void Update(T item)
    {
        Session.Update(item);
    }
}
public static class CustomerQueries
{
    public static IQueryable<Customer> ByName(
        this IQueryable<Customer> repo,
        string name)
    {
        return repo.Where(x => x.Name == name);
    }
    public static IQueryable<Customer> ByCity(
        this IQueryable<Customer> repo,
        string city)
    {
        return repo.Where(x => x.City == city);
    }
    
}
public class MyPage
{
    IRepository<Customer> _repository;
    public MyPage(IRepository<Customer> repository)
    {
        _repository = repository;
    }
    public Customer UpdateCustomer()
    {
        return _repository
            .ByCity("Aarhus")
            .ByName("Sebastien")
            .FirstOrDefault();
    }
}
public class when_filtering_by_city
{
    public void the_wong_city_is_not_selected()
    {
        var myTestData = new List<Customer>
        {
            new Customer { City = "Aarhus" },
            new Customer { City = "London" }
        };
        var funPlaceToBe = myTestData
            .AsQueryable()
            .ByCity("Aarhus")
            .FirstOrDefault();
        Debug.Assert(funPlaceToBe.City == "London");
    }
}
public class Customer
{
    public string Name { get; set; }
    public string City { get; set; }
}