I have some queries that I use all the time (like get rows only of some specific
ID: 645954 • Letter: I
Question
I have some queries that I use all the time (like get rows only of some specific type, or count something etc.). I'd like to organize them somehow (better then I currently do).
Currently I have them all in a static class called Queries which I don't really like because it's like a I-don't-know-how-to-name-this-class.
Is there a preferred way for organizing predefined queries in Entity Framework by extending some types etc.?
As requested here is an example showing how I use it:
All of my queries:
public static class Queries
{
public static IEnumerable<Light> GetEnabledLights()
{
using(var context = new MyEntities())
{
return context.Lights.Where(l => l.Enabled);
}
}
}
Code using some query:
public static class LightsLoader
{
public static void LoadLights()
{
var enabledLights = Queries.GetEnabledLights().ToList();
if (enabledLights.Count == 0)
{
throw new InvalidOperationException("There are no enabled lights.");
}
// ... more code
}
}
Faking the query and testing the business logic:
[TestClass]
public class LightsLoaderTests
{
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void TestNoEnableLights()
{
using(ShimContext.Create())
{
ShimQueries.GetEnabledLights = () => Enumerable.Empty<Light>();
LightsLoader.LoadLights();
}
}
}
But back to the question: I just thought Entity Framework might offer a better way for organizing queries then putting them all in a God-Class
Explanation / Answer
Extending the ORM Context is a good approach, but in a system with lots of predefined queries, I use to take another approach, using Extensions methods in order to group the related queries. Let me give an example:
The usage is kept simple like this:
var data = Context.Financial() // This returns a FinancialContextExtensions instance with all Financial grouped queries
.GetComplexReportData() // This returns the actual result for your query
.ToArray();
I create a file FinancialContextExtensions:
public static partial class ContextQueryExtensions
{
public static FinancialContextExtensions Financial(this DataContext context)
{
return new FinancialContextExtensions(context);
}
}
public class FinancialContextExtensions : ContextExtensions
{
protected readonly DataContext Context;
public FinancialContextExtensions(DataContext context)
{
this.Context = context;
}
public IEnumerable<FinancialReportInfo> GetComplexReportData(DateTime dateBeing, DateTime dateEnd)
{
return from a in Context.AAA
join b in Context.BBB on ...
where ...
group ...
select new FinancialReportInfo { ... };
}
}
PS: I don't know if this pattern has a name, but a I remember reading it on a site, don't know what site though...