我在存儲庫模式中使用Linq-to-SQL和Unity。我試圖在存儲庫方法[Securable]IQueryable<TEntity> List<TEntity>()
上添加一個對象安全攔截器,攔截該調用並僅返回用戶有權訪問的實體。LINQ to SQL with Unity Interception
public class SecurableAttribute : HandlerAttribute
{...}
public class SecurableHandler : ICallHandler
{
...
IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
var message = getNext()(input, getNext);
var returnType = message.ReturnValue.GetType();
if (typeof(IQueryable).IsAssignableFrom(returnType))
{
var entityType = returnType.GetGenericArguments().Single();
var securableAttribute = entityType.GetAttribute<SecurableTypeAttribute>();
if(securableAttribute != null)
{
//Build expression to filter the list from the attribute and primary key of the entity
//Return the new IQueryable
}
}
return message;
}
}
我已經建立了一個表情,但我不能這樣做,因爲message.ReturnValue.Where(expression)
的message.ReturnValue
是object
(message.ReturnValue
實際上是一個System.Data.Linq.Table<TEntity>
,但我不想太依賴於L2S),它是在因此我無法將其轉換回通用並替換爲message.ReturnValue
。
另外,我試過
public interface ISecurable<TKey>
{
TKey SecurityId { get; }
}
的實體,它鎖定我有點
,但我與確定,如果我能分開剩餘安全方面的問題。這使我在那裏我建立上述表達式做IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
如下:
if(typeof(ISecurableType).IsAssignableFrom(entityType))
{
var secured = ((IQueryable<ISecurable>)message.ReturnValue).Where(expression);
//Need to return secured as IQueryably<TEntity>
}
我現在已經投secured
到IQueryable<ISecurable>
但typeof(IQueryable<TEntity>).IsAssignableFrom(secured.GetType())
返回false,並換出的返回值拋出一個異常,但它似乎據我所知,可以延遲執行。 (另外,在設計時我不知道TEntity在SecurableHandler
,但我確實知道反射類型 - 但我已嘗試使用類聲明,我知道它在測試中。)
有什麼方法可以修改不知何故返回結果?我被困在需要返回一個我不知道在設計時間的泛型,從而使這不可能,但我也不能修改表達式(((IQueryable)message.ReturnType).Expression
被宣佈爲Expression Expression { get; }
)。
那裏有任何輝煌,可以指向我的方式有效嗎?
tl; dr需要返回IQueryable<TEntity>
在運行時從一個object
是一個Table<TEntity> : IQueryable<TEntity>
與一個額外的.Where(expression)
。
這工作完美! – Brian
好聽。樂於幫助。 –