Reputation: 9460
In the latest version of Lightswitch, they have added a query pipleline method that allows you to catch all query requests to the database, and add a filter. This allows you to add (for example) a filter that restricts the data to ones whose "active" flag is true, without having to worry about doing this on every query you write.
Now, given that the database level stuff in Lightswitch is all built on Entity Framework, I was wondering if there is something similar there. I am working on a very large project, with loads of queries in around 50 or 60 separate repositories, and don't really want to have to ask every developer to go through every query in every repository and add code to check the active flag. Apart from the time involved, the chances of missing a query are high, as are the chances of someone forgetting to include it in a future query.
Anyone know if this can be done at a low level in Entity Framework? Thanks
Upvotes: 2
Views: 1782
Reputation: 4803
You have to be able to intercept and modify your predicates.
One. If you've abstracted your repository then you could do something like this:
All your Entities could inherit from an Abstract class or Interface with and Active property and your code would be:
interface IActivatable {
bool IsActive {get;set;}
}
class Repository<EntityType>
where EntityType : class, IActivatable {
private StackOverflowEntities context;
public IQueryable<EntityType> GetAll() {
return context.Set<EntityType>().Where(e => e.IsActive == false);
}
}
That way the GetAll returns the IQueryable with an initial predicate, the rest will be added with an AND. Like so:
Repository<Person> persons;
var results = persons.GetAll().Where(p => p.IsMarried == false);
Which will result in a predicate equal to p.IsMarried == false && p.IsActive == false
Two. If it's not practical to change your repository code or code at all you could create a view for every table. The view can just include the IsActive in the where clause to exclude the records and then reload your EDMX based on those views - at least this is the way we used to do in back in the day.
Edit:
Three. If you have a generated DbContext exposed to client code you could do this:
public partial class StackOverflowEntities : DbContext
{
public StackOverflowEntities()
: base("name=StackOverflowEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Blog> Blogs {
return this.Set<Blog>().Where(b => b.IsActive == false);
}
}
Just means that you must turn off auto-code gen or modify the T4 template. Easier to just take the generated code, turn of the gen and modify.
Upvotes: 6