我在存储库模式中使用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
好听。乐于帮助。 –