在我的域模型中,我有一个基本实体类,所有类都派生于该实体类中
我希望能够根据当前用户的权限动态创建过滤器
例如 - 对于Employee类,我会定义一个员工可以看到自己和他的部门
我的方法会是这样的:
public static IQueryable<Employee> CreateLinqFilter(IQueryable<Employee> query, User user)
{
return query.Where(e => e.Id == user.Id || e.Department.Manager.Id == user.Id);
}
然后,在我的存储库基类中,我想动态确定类型并调用正确的CreateLinqFilter方法:
protected IQueryable CreateLinq<T>(User user)
{
var query = Session.Linq<T>();
Type t = typeof(T);
//if not an entity- do not perform filter
if (!t.IsAssignableFrom(typeof(Entity)))
{
return query;
}
//now we know that T is a sub-class of Entity.
return CreateLinqFilter<T>(query,user);
}
protected IQueryable CreateLinqFilter<T>(IQueryable<T> query, User user)
//the following line won't compile:
//where T: Entity
{
//i'd like to be able to do:
//T.CreateFilter(query);
//instead, I have to do this?
if (typeof(T) == Employee)
{
return Employee.CreateLinqFilter(query,user);
}
if (typeof(T) == Department)
{
return Department.CreateLinqFilter(query,user);
}
//etc...
}
到目前为止我唯一能解决的问题是很多if-else块,这些块很难看
谁有更好的主意?
感谢
的Jhonny
答案 0 :(得分:1)
尝试类似:
return (IQueryable)typeof(T).GetMethod("CreateLinqFilter").Invoke(null, new object[]{query, user});
这使用反射在运行时查找方法;如果这太慢,你可能想考虑在某处缓存GetMethod
的结果。注意,此方法不限于静态方法;用指向类型为T的对象的指针替换null,您也可以在普通实例方法上使用它。
有关详细信息,请参阅MSDN documentation for the reflection classes;你可以在documentation for Invoke中找到一个很好的例子。
答案 1 :(得分:0)
在c#4.0中,你可以使用动态a = T t,如果没有,也许你只能用第一个答案
答案 2 :(得分:0)
好吧,首先,不要使用很多if..else块,使用开关。
答案 3 :(得分:0)
非常好的解决方案,IMO只是在派生的存储库类中而不是在基础存储库中调用该方法。那么你没有问题,因为派生类知道它在查询什么,所以EmployeesRepository将显式调用Employee.GetFilter。