Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7715737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T02:27:46+00:00 2026-06-01T02:27:46+00:00

In my project I am using the following approach to querying data from the

  • 0

In my project I am using the following approach to querying data from the database:

  1. Use a generic repository that can return any type and is not bound to one type, i.e. IRepository.Get<T> instead of IRepository<T>.Get. NHibernates ISession is an example of such a repository.
  2. Use extension methods on IQueryable<T> with a specific T to encapsulate recurring queries, e.g.

    public static IQueryable<Invoice> ByInvoiceType(this IQueryable<Invoice> q,
                                                    InvoiceType invoiceType)
    {
        return q.Where(x => x.InvoiceType == invoiceType);
    }
    

Usage would be like this:

var result = session.Query<Invoice>().ByInvoiceType(InvoiceType.NormalInvoice);

Now assume I have a public method I want to test that uses this query. I want to test the three possible cases:

  1. The query returns 0 invoices
  2. The query returns 1 invoice
  3. The query returns multiple invoices

My problem now is: What to mock?

  • I can’t mock ByInvoiceType because it is an extension method, or can I?
  • I can’t even mock Query for the same reason.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T02:27:47+00:00Added an answer on June 1, 2026 at 2:27 am

    After some more research and based on the answers here and on these links, I decided to completely re-design my API.

    The basic concept is to completely disallow custom queries in the business code. This solves two problems:

    1. The testability is improved
    2. The problems outlined in Mark’s blog post can no longer happen. The business layer no longer needs implicit knowledge about the datastore being used to know which operations are allowed on the IQueryable<T> and which are not.

    In the business code, a query now looks like this:

    IEnumerable<Invoice> inv = repository.Query
                                         .Invoices.ThatAre
                                                  .Started()
                                                  .Unfinished()
                                                  .And.WithoutError();
    
    // or
    
    IEnumerable<Invoice> inv = repository.Query.Invoices.ThatAre.Started();
    
    // or
    
    Invoice inv = repository.Query.Invoices.ByInvoiceNumber(invoiceNumber);
    

    In practice this is implemented like this:

    As Vytautas Mackonis suggested in his answer, I am no longer depending directly on NHibernate’s ISession, instead I am now depending on an IRepository.

    This interface has a property named Query of type IQueries. For each entity the business layer needs to query there is a property in IQueries. Each property has its own interface that defines the queries for the entity. Each query interface implements the generic IQuery<T> interface which in turn implementes IEnumerable<T>, leading to the very clean DSL like syntax seen above.

    Some code:

    public interface IRepository
    {
        IQueries Queries { get; }
    }
    
    public interface IQueries
    {
        IInvoiceQuery Invoices { get; }
        IUserQuery Users { get; }
    }
    
    public interface IQuery<T> : IEnumerable<T>
    {
        T Single();
        T SingleOrDefault();
        T First();
        T FirstOrDefault();
    }
    
    public interface IInvoiceQuery : IQuery<Invoice>
    {
        IInvoiceQuery Started();
        IInvoiceQuery Unfinished();
        IInvoiceQuery WithoutError();
        Invoice ByInvoiceNumber(string invoiceNumber);
    }
    

    This fluent querying syntax allows the business layer to combine the supplied queries to take full advantage of the underlying ORM’s capabilities to let the database filter as much as possible.

    The implementation for NHibernate would look something like this:

    public class NHibernateInvoiceQuery : IInvoiceQuery
    {
        IQueryable<Invoice> _query;
    
        public NHibernateInvoiceQuery(ISession session)
        {
            _query = session.Query<Invoice>();
        }
    
        public IInvoiceQuery Started()
        {
            _query = _query.Where(x => x.IsStarted);
            return this;
        }
    
        public IInvoiceQuery WithoutError()
        {
            _query = _query.Where(x => !x.HasError);
            return this;
        }
    
        public Invoice ByInvoiceNumber(string invoiceNumber)
        {
            return _query.SingleOrDefault(x => x.InvoiceNumber == invoiceNumber);
        }
    
        public IEnumerator<Invoice> GetEnumerator()
        {
            return _query.GetEnumerator();
        }
    
        // ...
    } 
    

    In my real implementation I extracted most of the infrastructure code into a base class, so that it becomes very easy to create a new query object for a new entity. Adding a new query to an existing entity is also very simple.

    The nice thing about this is that the business layer is completely free of querying logic and thus the data store can be switched easily. Or one could implement one of the queries using the criteria API or get the data from another data source. The business layer would be oblivious to these details.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Currently, we're using the following version numbering scheme for our C# winforms project: Major
I am using the three20 open source project by Joe Hewitt. have the following
I created an iPhone project using the Core Data template. Now when I try
I came across this article on Code Project that talks about using an abstract
I'm using LINQ-to-Entities. Using the following query: var x = from u in context.Users
I created a Java Project in Eclipse using the Web services Top down approach
Soon I will be involved in a project that will be using the agile
Using the model-first approach, I made 2 entities: Project and User. A project has
Let's suppose I have the following structure in my project (I'm using iBatis as
I am trying to write a project using the code-first approach and I have

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.