2011-01-13 57 views
2

在我的域模型中,我有一個基類實體類,所有類都從中派生出來。
我希望能夠根據當前用戶的權限動態創建過濾器。
例如 - 對於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

我幾乎可以肯定地錯過了這裏的東西,但爲什麼你不只是在你的實體類聲明一個「CreateLinqFilter」,然後而不是所有這些relkin類型的東西,或者只是如果聲明不能只是調用「entity.CreateLinqFilter並且它只是把它稱爲正確的東西?正如我所說,我可能錯過了一些東西,我想知道什麼.-) – Chris 2011-01-13 15:15:35

+0

@Chris,因爲CreateLinqFilter函數對實體的* Collections *有效,它很漂亮在一個單一的實體環境中沒有意義;函數實際上是靜態的... – 2011-01-16 13:11:54

+0

啊,是的,這是有道理的,我偶爾也會遇到困難,我的腦袋在仿製藥和他們需要居住的地方:) – Chris 2011-01-17 10:38:44

回答

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找到一個很好的例子。

0

在C#4.0中,你可以使用一個動態= T T,如果沒有,也許你只能使用第一個答案

0

嗯,首先,不要用大量的if..else塊,使用開關。

0

這是一個非常好的解決方案,IMO只是在派生的資源庫類中調用方法,而不是在基礎資源庫中調用。那麼你沒有問題,因爲派生類知道它在查詢什麼,所以EmployeesRepository將顯式調用Employee.GetFilter。