I often see example repository patterns that look like this:
public interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAllByName(string name);
}
But how do you handle cases where you may need to do a complex search? I don't think it would be a good idea to add many methods to the interface that would make it end up looking like:
IEnumerable<T> GetAllByFirstName(string name);
IEnumerable<T> GetAllByLastName(string name);
IEnumerable<T> GetAllByFirstAndLastName(string name);
IEnumerable<T> GetAllByAddress(string name);
...
...
...
Use the Predicate Builder to dynamically build the where condition
public interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate);
}
Then build the conditions
var predicate = PredicateBuilder.True<Customer>();
if (!string.IsNullOrEmpty(FirstName))
{
predicate = predicate.And(d => d.FirstName.Contains(FirstName));
}
if (!string.IsNullOrEmpty(LastName))
{
predicate = predicate.And(d => d.LastName.Contains(LastName));
}
var products = productRepo.GetAllBy(predicate);
Create a class to pass the search criteria
public class CustomerFilterCriteria
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
public interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAllBy(CustomerFilterCriteria criteria);
}
Question : Why make the repository generic if you are going to be exposing type specific methods (or do all your entities have FirstName, LastName, Address etc?).
If your underlying data resources are LINQ expression tree enabled, a common signature would also be generic, e.g.
IEnumerable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)
And if you want your queries to be 'stackable', you could expose an IQueryable
IQueryable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)
You could add a filtermodel and check which filters have been filled like so:
IEnumerable<T> GetAllByFiilter(FilterModel filter);
public class FilterModel {
public string Lastname {get;set;}
public string Firstname {get;set;}
}
public IEnumerable<T> GetAllByFilter(FilterModel filter) {
if(!string.IsNullOrWhiteSpace(filter.Lastname) {
//add restriction
}
// .. etc ..
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With