Search code examples
c#nhibernatequeryover

How to apply IQueryOver<TRoot> methods to IQueryOver?


I'm wrapping QueryOver with the interface IQueryOver. Thanks UnderlyingCriteria I can access to the criteria.

I'd like to use the IQueryOver methods such as Take, Skip ...

My intention is to have a list of func to apply, in this scenario I have a

public IQueryOver QueryOver { get; set; }

/// <summary>
/// Set paging (before querying!)
/// </summary>
/// <param name="pageNumber"></param>
/// <param name="pageSize"></param>
public void Paging(int pageNumber, int pageSize)
{
    if (pageNumber > 0 && pageSize > 0)
    {
        _pageSize = pageSize;
        _pageNumber = pageNumber;

        NHibernate.ICriteria paging(IQueryOver str) => str.UnderlyingCriteria.SetFirstResult(pageSize * (pageNumber - 1)).SetMaxResults(pageSize);

        _funcs.Add(paging);
    }
}

Then I'd like to wrap List

public IList<T> List()
{
    IList<T> result = null;
    try
    {
        BeginTransaction();
        try
        {
            //foreach (var func in _funcs)
            //{
            //  QueryOvern = func.Invoke(QueryOver); // THIS CANT'T WORKS
            //}



            result = QueryOver.UnderlyingCriteria.
                     SetResultTransformer(Transformers.AliasToBean<T>()).
                     List<T>();

        }
        catch (Exception ex)
        {
            log.Error(System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
            result = new List<T>();
            RollBackTransaction();
        }

    }
    catch (Exception ex)
    {
        log.Error(System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
    }
    return result;
}

This works, I mean the List() works but wow can apply the func to the IQueryOver from ICriteria?

Thanks in advance


Solution

  • Shame of me, every time it applys a criteria UnderlyngCriteria adds it. So _criterias is a list of Action

    private readonly IList<Action<IQueryOver>> _criterias = null; // [instantiated into constructor]
    
    public void Paging(int pageNumber, int pageSize)
    {
        if (pageNumber > 0 && pageSize > 0)
        {
            _pageSize = pageSize;
            _pageNumber = pageNumber;
    
            void paging(IQueryOver queryOver) => queryOver.Paging(pageNumber, pageSize);
    
            _criterias.Add(paging);
        }
    }
    

    then it can be applyed

    public IList<T> List()
    {
        IList<T> result = null;
        try
        {
            BeginTransaction();
            try
            {
                foreach (var criteria in _criterias)
                {
                    criteria.Invoke(QueryOver);
                }
    
                result = QueryOver.UnderlyingCriteria.
                         SetResultTransformer(Transformers.AliasToBean<T>()).
                         List<T>();
    
            }
            catch (Exception ex)
            {
                log.Error(System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
                result = new List<T>();
                RollBackTransaction();
            }
    
        }
        catch (Exception ex)
        {
            log.Error(System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
        }
        return result;
    }
    

    I made a extension method to paging

    public static class CustomExtensions
    {
        public static NHibernate.ICriteria Paging(this IQueryOver queryOver, int pageNumber, int pageSize)
        {
    
            return queryOver.UnderlyingCriteria.SetFirstResult(pageSize * (pageNumber - 1)).SetMaxResults(pageSize);
    
        }
    }