In some O/RMs, it is possible to specify automatic filters for entity collections such as one-to-many or many-to-many. These are applied automatically whenever these collections are being populated. Entity Framework does not offer one such mechanism, however, it is possible to implement it.
In Entity Framework Code First, entities are exposed as IDbSet<T> or DbSet<T> collections on a context, a DbContext-derived class. There is no way to automatically set a filter that will apply to all queries coming from these collections, unless we create our own IDbSet<T> class. Let’s call it FilteredDbSet<T> and have it implement the same interfaces as DbSet<T> so that it can be used instead of it transparently:
In the constructor of our DbContext, we create instances of this class, and pass a LINQ restriction query on its constructor:
From now on, all queries over the Bases collection will be restricted.
A different matter is collections on entities. For these, we usually declare a property of ICollection<T> and let Entity Framework create an instance for us, when it is loading the entity. The class responsible for creating this instance is DbCollectionEntry, which unfortunately does not allow subclassing, because it doesn’t have any public or protected constructors or virtual methods. Let’s take a different path and create our own collection class instead:
This collection receives a pointer to a possibly existing collection and a DbCollectionEntry responsible for loading this collection. We must use a bit of reflection magic to let DbCollectionEntry think that the collection was already loaded (IsLoaded), and instead load it ourselves, by applying our custom restriction to the expression returned by its Query method.
We use this extension method like this:
This will pick the Product entity from the Products context collection and filter its Details collection.
As you can see, even though Entity Framework does not have all functionality that we might be used to, it still offers enough extensibility points that allow us to built it ourselves. The same technique that I presented here can be used for building lazy loaded or even IQueryable<T> collections, both interesting ideas that I leave as an exercise to you!