Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I realize this is old, but I've been dealing with this same issue lately, and I came to the same conclusion as Chad: with a little discipline, a hybrid of extension methods and repository methods seems to work best.</p> <p>Some general rules I've been following in my (Entity Framework) application:</p> <h2>Ordering queries</h2> <p>If the method is used only for ordering, I prefer to write extension methods that operate on <code>IQueryable&lt;T&gt;</code> or <code>IOrderedQueryable&lt;T&gt;</code> (to leverage the underlying provider.) <em>e.g.</em></p> <pre><code>public static IOrderedQueryable&lt;TermRegistration&gt; ThenByStudentName( this IOrderedQueryable&lt;TermRegistration&gt; query) { return query .ThenBy(reg =&gt; reg.Student.FamilyName) .ThenBy(reg =&gt; reg.Student.GivenName); } </code></pre> <p>Now I can use <code>ThenByStudentName()</code> as needed within my repository class.</p> <h2>Queries returning single instances</h2> <p>If the method involves querying by primitive parameters, it usually requires an <code>ObjectContext</code> and can't be easily made <code>static</code>. These methods I leave on my repository, <em>e.g.</em></p> <pre><code>public Student GetById(int id) { // Calls context.ObjectSet&lt;T&gt;().SingleOrDefault(predicate) // on my generic EntityRepository&lt;T&gt; class return SingleOrDefault(student =&gt; student.Active &amp;&amp; student.Id == id); } </code></pre> <p>However, if the method instead involves querying an <code>EntityObject</code> using its <a href="http://msdn.microsoft.com/en-us/library/bb738520.aspx" rel="nofollow">navigation properties</a>, it can usually be made <code>static</code> quite easily, and implemented as an extension method. <em>e.g.</em></p> <pre><code>public static TermRegistration GetLatestRegistration(this Student student) { return student.TermRegistrations.AsQueryable() .OrderByTerm() .FirstOrDefault(); } </code></pre> <p>Now I can conveniently write <code>someStudent.GetLatestRegistration()</code> without needing a repository instance in the current scope.</p> <h2>Queries returning collections</h2> <p>If the method returns some <code>IEnumerable</code>, <code>ICollection</code> or <code>IList</code>, then I like to make it <code>static</code> if possible, and leave it on the repository <em>even if it uses navigation properties.</em> <em>e.g.</em></p> <pre><code>public static IList&lt;TermRegistration&gt; GetByTerm(Term term, bool ordered) { var termReg = term.TermRegistrations; return (ordered) ? termReg.AsQueryable().OrderByStudentName().ToList() : termReg.ToList(); } </code></pre> <p>This is because my <code>GetAll()</code> methods already live on the repository, and it helps to avoid a cluttered mess of extension methods. </p> <p>Another reason for not implementing these "collection getters" as extension methods is that they would require more verbose naming to be meaningful, since the return type isn't implied. For example, the last example would become <code>GetTermRegistrationsByTerm(this Term term)</code>.</p> <p>I hope this helps!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload