/// <summary>
        /// Returns <see cref="IQueryResult{T}"/> that satisfy the given <paramref name="constraints"/> on the table.
        /// </summary>
        /// <typeparam name="TBusinessEntity">The type of BusinessObject of source table.</typeparam>
        /// <param name="constraints">QueryConstraints object to be satisfied.</param>
        /// <returns>The result records that satisfy the given <paramref name="constraints"/>.</returns>
        /// <exception cref="RepositoryException">When an error on the database level is occurred and couldn't be recovered.</exception>
        public IQueryResult <TBusinessEntity> Find <TBusinessEntity>(IQueryConstraints <TBusinessEntity> constraints)
            where TBusinessEntity : class, new()
        {
            try
            {
                using (ShoppingListContext context = new ShoppingListContext())
                {
                    IQueryResult <TBusinessEntity> results = null;

                    // get the appropriate cache key for this query
                    string key = Cache.CacheKey(constraints);

                    // check if it's in the cache already
                    if (!Cache.Provider.TryGet(key, out results))
                    {
                        Debug.WriteLine($"NOT FOUND cache for: {key}");

                        // if not, then run the query
                        results = context.Set <TBusinessEntity>().ToSearchResult(constraints);

                        // and cache the results for next time
                        Cache.Provider.Set(key, results);
                    }
                    else
                    {
                        Debug.WriteLine($"Found cache for: {key}");
                    }

                    // return the results either from cache or that were just run
                    return(results);
                }
            }
            catch (Exception ex)
            {
                throw ThrowHelper.ReThrow <TBusinessEntity>(ex);
            }
        }