(Documentation still under construction)

The page contains the following sections:


IQueryRepository contains 2 main overloaded methods:
  • GetEntity<T>
  • GetEntities<T>
The GetEntity<T> method returns a single entity and by default throws an EntitySearchRepositoryException if the result is not equal to 1. The GetEntities<T> returns an list of IQueryable<T> entities. Both methods can be fully customised using the a couple of strategy pattern implementations which are described in the following section


Query Strategies are fundamental to IQueryRepository. They allow the data ( via the Queryable )to be filtered and ordered and where Entity Framework is concerned allow for additional statements to be appended to the linq query, statements such as eager loading (include) and no tracking. NRepository has 2 flavours of strategy patterns that ituses:
Each strategy can be chained to create more complex strategies and using the Condition extension method means that these more complex strategies can occur in-line rather multiple if statements to build up the necessary strategy (See main help page for example)


This is a general strategy that can be used to add additional statements to the IQueryable<T> object. Data can be filtered, ordered, using entity framework the eager loading of entities can all be performed using this type of strategy. An implementation of this type of strategy can be seen below:

  public class FilterByEffectiveDateProductQueryStrategy : QueryStrategy
        private readonly DateTime? effectiveDate;

        public FilterByEffectiveDateProductQueryStrategy(DateTime effectiveDate)
            if (effectiveDate != DateTime.MinValue)
                this.effectiveDate = effectiveDate;

        public override IQueryable<T> GetQueryableEntities<T>(object additionalData)
            if (!typeof(Product).IsAssignableFrom(typeof(T)))
                throw new ApplicationException("Only types derived from product can be used with this strategy: " + GetType().Name);

            var query = QueryableRepository.GetQueryableEntities<T>(additionalData);
            if (this.effectiveDate == null || !this.effectiveDate.HasValue)
                return query;

            var filteredQuery = query.OfType<Product>().Where(p =>
                    e => e.EffectiveFrom <= effectiveDate &&
                        (e.EffectiveUntilDate >= effectiveDate || e.EffectiveUntilDate == null)));

            return (IQueryable<T>)filteredQuery;


This type of strategy is a derivative of IQueryStrategy but can only be used for filtering data. One of the benefits of this strategy type is that you can combine these strategies using the And, Or & Not operators.

            //  All persons that contain Peter in the name but not those that also contain Pan
            persons = repository.GetEntities<Person>(
                   new TextSearchSpecificationStrategy<Person>(p => p.Name, "Peter") & !
                   new TextSearchSpecificationStrategy<Person>(p => p.Name, "Pan"));
            // All persons where Peter is not found in the name
            persons = repository.GetEntities<Person>(
                   !new TextSearchSpecificationStrategy<Person>(p => p.Name, "Peter"));

A simple but powerful text search specification strategy can be seen below :

    public class TextSearchSpecificationStrategy<TEntity> : SpecificationQueryStrategy<TEntity> where TEntity : class
        private Expression<Func<TEntity, bool>> _Expression;

        public TextSearchSpecificationStrategy(Expression<Func<TEntity, object>> propertyName, string searchString, bool isCaseSensitive = false)
            : this(PropertyInfo<TEntity>.GetMemberName(propertyName), searchString, isCaseSensitive)

        public TextSearchSpecificationStrategy(string propertyName, string searchString, bool isCaseSensitive = false)
            if (String.IsNullOrEmpty(propertyName))
                throw new ArgumentException("propertyName is null or empty.", "propertyName");

            if (String.IsNullOrEmpty(searchString))
                throw new ArgumentException("searchString is null or empty.", "searchString");

            IsCaseSensitive = isCaseSensitive;
            PropertyName = propertyName;
            SearchString = searchString;

            _Expression = CreateSearchExpression(PropertyName, SearchString, IsCaseSensitive);

        public string SearchString
            private set;

        public string PropertyName
            private set;

        public bool IsCaseSensitive
            private set;

        public override Expression<Func<TEntity, bool>> SatisfiedBy()
            return _Expression;

        private static Expression<Func<TEntity, bool>> CreateSearchExpression(string propertyName, string searchString, bool isCaseSensitive)
            var paramExp = Expression.Parameter(typeof(TEntity), "type");
            var propExp = Expression.Property(paramExp, propertyName);
            var methodInfo = typeof(string).GetMethod("Contains", new[] { typeof(string) });

            if (!isCaseSensitive)
                var valueExp2 = Expression.Constant(searchString.ToUpper(), typeof(string));
                var toUpperMethodInfo = typeof(string).GetMethod("ToUpper", new Type[0]);
                var upperCall = Expression.Call(propExp, toUpperMethodInfo, null);
                var methCall2 = Expression.Call(upperCall, methodInfo, valueExp2);
                return Expression.Lambda<Func<TEntity, bool>>(methCall2, paramExp);

            var valueExp = Expression.Constant(searchString, typeof(string));
            var methCall = Expression.Call(propExp, methodInfo, valueExp);
            return Expression.Lambda<Func<TEntity, bool>>(methCall, paramExp);

Included Strategies

Below are a list of the available strategies in both NRepository.Core & NRepository.EntityFramework assemblies,

            new TextSearchSpecificationStrategy<Person>(p => p.Name, "Pet", isCaseSensitive:true) |
            new ExpressionSpecificationQueryStrategy<Person>(p => true);

            new ExpressionQueryStrategy<Person>(p => p.Name == "A Name");
            new AggregateQueryStrategy(new DefaultQueryStrategy());
            new ConditionalAggregateQueryStrategy(true,new DefaultQueryStrategy());
            new ConditionalQueryStrategy(true,new DefaultQueryStrategy());
            new OfTypeQueryStrategy(typeof(Person));
            new OrderByDescendingQueryStrategy("Name");
            new OrderByDescendingQueryStrategy<Person>(p => p.Partner.Name);
            new ThenByDescendingQueryStrategy("Name");
            new ThenByDescendingQueryStrategy<Person>(p => p.Partner.Name);
            new OrderByQueryStrategy("Name");
            new OrderByQueryStrategy<Person>(p => p.Partner.Name);
            new ThenByQueryStrategy("Name");
            new ThenByQueryStrategy<Person>(p => p.Partner.Name);
            new PagingQueryStrategy(5,10);
            new TakeQueryStrategy(5);
            new SkipQueryStrategy(10);
            new ReverseQueryStrategy();

            // NRepository.Entity Stragegies
            new AsNoTrackingQueryStrategy();
            new EagerLoadingQueryStrategy("Name");
            new EagerLoadingQueryStrategy<Person>(
                p => p.Children,
                p => p.Partner);

Advanced Features

Documentation 'not yet implemented'

Interceptions, projections and Anti corruption layers

Documentation 'not yet implemented'


Documentation 'not yet implemented'

Sample code

Enjoy ;)

            var data = new List<object>
                new Person{Name = "Billy Bob", Partner= new Person{ Name= "Mrs P. Bob"}},
                new Person{Name = "Bobby Bob", Partner= new Person{ Name= "Mrs T. Bob"}},
                new Person{Name = "Peter Pan"},
                new Person{Name = "Peter Jackson"},
                new Person{Name = "Billy Ocean", Partner=new Person{Name = "Phil Collins"}},
                new Person{Name = "Peter Parker",Partner = new Person{Name = "Aunt May"}},
                new Person{Name = "Bat Man", Partner = new Person{Name = "Robin"}},
                "A string which shows",
                "data can contain any type of items"

            var repository = new InMemoryRepository(data);

            // Get all entities
            var persons = repository.GetEntities<Person>();

            // Simple Query 
            persons = repository.GetEntities<Person>();

            // Filtering
            persons = repository.GetEntities<Person>(p => p.Name == "Name");

            //  All persons that contain Peter in the name but not those that also contain Pan
            persons = repository.GetEntities<Person>(
                   new TextSearchSpecificationStrategy<Person>(p => p.Name, "Peter", false) & !
                   new TextSearchSpecificationStrategy<Person>(p => p.Name, "Pan", false),
                   new OrderByQueryStrategy("Name"));
            // All persons where Peter is not found in the name
            persons = repository.GetEntities<Person>(
                   !new TextSearchSpecificationStrategy<Person>(p => p.Name, "Peter", false));

            // none filtering strategies
            persons = repository.GetEntities<Person>(
                new OrderByQueryStrategy<Person>(p => p.Name));

            // ***********************************************************
            // ENtityFramework
            repository = new EntityFrameworkRepository(new MyDbContext());

            // Entity framework strategies (Explicit Loading and no tracking)
            persons = repository.GetEntities<Person>(
               new AsNoTrackingQueryStrategy(),
               new EagerLoadingQueryStrategy<Person>(
                   p => p.Children,
                   p => p.Partner));

            // Explicit Loading
            var person = repository.GetEntity<Person>(p => p.Name == "Peter Parker");
            repository.Load(person,p => p.Partner);

            // Explicit loading with filtering usig expression
            person = repository.GetEntity<Person>(p => p.Name == "Peter Parker");
            repository.Load(person, p => p.Children, p => p.Name.Count() > 6);

            // Explicit loading with filtering usig specification query strategy
            person = repository.GetEntity<Person>(p => p.Name == "Peter Parker");
            repository.Load(person, p => p.Children, new ExpressionSpecificationQueryStrategy<Person>(p => p.Name.Count() > 6));

            // Update the entity state of an object
            repository.UpdateEntityState(person, EntityState.Detached);

            // Add an entity
            repository.Add(new Person());

            // Save entities

Last edited Jun 28, 2014 at 6:13 PM by KelbobK5, version 5