В одном и проектов был разработан слой доступа к данным через паттерн Repository и Entity Framework 4 (code only). Интерфейс репозтория выглядел следующим образом:
public interface IRepository<T> where T : class
{
IEnumerable<T> Find(Func<T, bool>; where);
IEnumerable<T> Find(Specification<T> specification);
T Single(Func<T, bool> where);
T Single(Specification<T> specification);
void Delete(T entity);
void Add(T entity);
}
Пока все хорошо, но при реализации первого же метода и анализе запроса к базе данных было обнаружено (
Решение очень протое. Вместо использования предикатов типа:
Func<T, bool>необходимо использовать:
Expression<Func<TEntity, bool>>
Для полноты приведу пример реализации интерфейса репозитория
public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly IObjectContext _objectContext = null;
private readonly IObjectSet<TEntity> _objectSet = null;
public BaseRepository(IObjectContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
_objectContext = objectContext;
_objectSet = _objectContext.CreateObjectSet<TEntity>();
}
protected IQueryable<TEntity> GetQuery()
{
return _objectSet;
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> where)
{
return _objectSet.Where(where);
}
public IEnumerable<TEntity> Find(Specification<TEntity> specification)
{
return specification.SatisfyingElementsFrom(GetQuery());
}
public TEntity Single(Specification<TEntity> specification)
{
return _objectSet.SingleOrDefault(specification.MatchingCriteria);
}
public TEntity Single(Expression<Func<TEntity, bool>> where)
{
return _objectSet.SingleOrDefault(where);
}
public void Delete(TEntity entity)
{
_objectSet.DeleteObject(entity);
}
public void Add(TEntity entity)
{
_objectSet.AddObject(entity);
}
}
Полезные ссылки:


