Using Entity Framework’s Find method with predicate
Today I spotted #efhelp
question on Twitter about using Find
method but with predicate.
The Find
method is smart. It first checks whether the record with given key(s) is present in current DbContext
locally and if so it returns it. Else it sends the query into database and returns what database has. Sadly the method only accepts key(s), not a i.e. predicate.
But thanks to Local
property on DbSet
it’s not that difficult to create similar behavior.
public static IEnumerable<T> FindPredicate<T>(this DbSet<T> dbSet, Expression<Func<T, bool>> predicate) where T : class
{
var local = dbSet.Local.Where(predicate.Compile());
return local.Any()
? local
: dbSet.Where(predicate).ToArray();
}
public static async Task<IEnumerable<T>> FindPredicateAsync<T>(this DbSet<T> dbSet, Expression<Func<T, bool>> predicate) where T : class
{
var local = dbSet.Local.Where(predicate.Compile());
return local.Any()
? local
: await dbSet.Where(predicate).ToArrayAsync().ConfigureAwait(false);
}
The method first checks “local” source, if there’s nothing – either the record(s) are really not in memory yet or the predicate doesn’t match anything (2nd item is important to keep in mind) – it hits the database. For convenience I also included asynchronous version of the same method.