I'm checking out possibilities with a generic repository using Entity framework (object context).
I have an interface
interface IRepository<T> where T : class
{
IList<T> GetItems(Func<T, bool> Where, params string[] Navigations);
}
And the class implementing the interface
class GenericRepository<T> : IRepository<T> where T : class
{
public IList<T> GetItems(Func<T, bool> Where, params string[] Navigations)
{
List<T> list;
using(var ctx = new Context())
{
IQueryable<T> query = ctx.CreateObjectSet<T>();
foreach (string nav in Navigations)
(query as ObjectQuery<O>).Include(nav);
list = query.Where(Where).ToList<T>();
}
return list;
}
}
Then I have another class extending GenericRepository. And implementing another interface(not import right now since that interface currently just extends IRepository with no features added).
class EmployeeRepository : GenericRepository<Employee>, IEmployeeRepository
{
}
When I want to fetch data from my repository I do something like this:
private void Test()
{
IEmployeeRepository rep = new EmployeeRepository();
IList<Employee> list = rep.GetItems(
e => e.Department.Name.Contains("Os")
&& e.Role.Type == 2,
"Department", "Role"
);
}
And here I get an error saying e.Department is null (I believe I get one on Role as well).
The model has three entities
Department 1..* Employee Role 1..1 Employee
Is it possible to add predictions on references tables like I do? (with some changes).
Thanks!
First, use Expression<Func<T, bool>>
instead of Func<T, bool>
.
If you use Func<T, bool>
, you will enumerate before applying your predicate !
It may be enough.
If it's not, add some null checks.
IList<Employee> list = rep.GetItems(
e => e.Department != null && e.Department.Name.Contains("Os")
&& e.Role != null && e.Role.Type == 2,
"Department", "Role"
);
Finally, I would change the implementation of GenericRepository to
class GenericRepository<T> : IRepository<T> where T : class
{
public IList<T> GetItems(Expression<Func<T, bool>> predicate, params string[] navigationProperties)
{
List<T> list;
using(var ctx = new Context())
{
var query = ctx.Set<T>().AsQueryable();
foreach (string navigationProperty in navigationProperties)
query = query.Include(navigationProperty);//got to reaffect it.
list = query.Where(predicate).ToList<T>();
}
return list;
}
}
You are sure that all employees have a department? And that that department is loaded? otherwise i would add a check if e.Department <> null
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.