我正在使用ado.net数据服务,并希望在查询拦截器中实现行级安全性,以限制数据仅返回允许用户查看的数据。 复杂性在于用户的用户名在另一个表上。所以我想我可以根据该用户的OnlineSubscription表中的条目检索用户可以看到的事件列表,然后返回当前事件是否与返回的任何条目匹配,如下所示:
[QueryInterceptor("Events")]
public Expression<Func<Events, bool>> QueryEvents()
{
var allowedEventList = (from os in context.OnlineSubscription
from e in os.Events
where os.UserName == HttpContext.Current.User.Identity.Name
select e;
return e => events.Intersect(new List<Events>
{
e
}).Any();
}
然而,这会引发“未实现”异常。所以我的问题是:是否有正确的方法将当前实体与查询拦截器中的实体列表进行比较?
编辑:我也试过了:return e => events.Any(evnt => evnt.Event_Key == e.Event_Key);
没有任何成功(再次获得“未实施”例外)。
答案 0 :(得分:2)
显然这会因为使用lambda表达式事件而失败。任何...它已经在初始上下文中查询(即直接查询事件)然后当你添加events.Any子句时它也会尝试查询新的上下文(即OnlineSubscription中嵌套的“from”)因此可以理解地引发异常。
然后我用了:
[QueryInterceptor("Events")]
public Expression<Func<Events, bool>> QueryEvents()
{
return e => e.OnlineSubscription.Any(os => os.UserName == HttpContext.Current.User.Identity.Name);
}
哪个有效,因为这只是在与初始查询相同的上下文中进行查询,而只是遍历关系。
答案 1 :(得分:0)
真的?我使用此代码获得“未实现”异常:
[QueryInterceptor("Products")]
public Expression<Func<Product, bool>> QueryProducts()
{
return p => p.User.Username == HttpContext.Current.User.Identity.Name;
}
如果我按照Product对象本身的属性进行过滤,但不能通过任何关系进行过滤,那么它可以正常工作。