【发布时间】:2015-12-30 20:00:48
【问题描述】:
我正在使用 SharePoint CSOM。这使用基于表达式的查询语言来指定要检索的数据。我正在开发的系统会进行几个不同的查询,但它们都需要包含某些数据以进行安全检查。例如:
using (ClientContext context = new ClientContext(weburl))
{
var subwebs = context.Web.GetSubwebsForCurrentUser(new SubwebQuery());
context.Load(subwebs,
webs => webs.Include(
// BEGIN security-related boilerplate
web => web.RoleAssignments.Include(
ra => ra.Member,
ra => ra.RoleDefinitionBindings.Include(
rdb => rdb.BasePermissions,
rdb => rdb.RoleTypeKind
)
),
// END security-related boilerplate
web => web.Title,
web => web.ServerRelativeUrl));
context.ExecuteQuery();
}
我试图避免在每个需要它们的地方复制/粘贴与安全相关的表达式。对Include 方法的检查表明,它将表达式列表作为参数:
IQueryable<TSource> Include<TSource>(
this IQueryable<TSource> clientObjects,
params Expression<Func<TSource, object>>[] retrievals)
where TSource : ClientObject
所以我创建了一个返回所需表达式的扩展方法:
public static Expression<Func<T, object>> GetSecurityExpression<T>(this ClientObjectCollection<T> list)
where T : SecurableObject
{
return x => x.RoleAssignments.Include(
ra => ra.Member,
ra => ra.RoleDefinitionBindings.Include(
rdb => rdb.BasePermissions,
rdb => rdb.RoleTypeKind
)
);
}
查询被重写如下:
using (ClientContext context = new ClientContext(weburl))
{
var subwebs = context.Web.GetSubwebsForCurrentUser(new SubwebQuery());
context.Load(subwebs,
webs => webs.Include(
subwebs.GetSecurityExpression(),
web => web.Title,
web => web.ServerRelativeUrl));
context.ExecuteQuery();
}
这编译得很好,但在运行时它会抛出一个Microsoft.SharePoint.Client.InvalidQueryExpressionException:
查询表达式 '值(Microsoft.SharePoint.Client.WebCollection).GetSecurityExpression()' 不支持。
如果我正确理解异常,编译器不会调用subwebs.GetSecurityExpression(),而是从中创建一个表达式并将其传递给Include。
我发现的解决方法是这样编写调用代码:
using (ClientContext context = new ClientContext(weburl))
{
var subwebs = context.Web.GetSubwebsForCurrentUser(new SubwebQuery());
var securityExpression = subwebs.GetSecurityExpression();
context.Load(subwebs,
webs => webs.Include(
securityExpression,
web => web.Title,
web => web.ServerRelativeUrl));
context.ExecuteQuery();
}
这可行,但并不像我希望的那样简洁。有没有办法让第一种方法发挥作用?
【问题讨论】:
标签: c# sharepoint lambda iqueryable