构建动态 Lambda 表达式以比较未定义数量的值
Build dynamic Lambda Expression for comparing undefined number of values
简而言之,我想要完成的是使用 CSOM 从 SharePoint Project Server 中的项目加载任务。
var projects = ctx.LoadQuery(ctx.Projects
.Where(p => p.Id == projGuid)
.Include(
p => p.Id, p => p.Name,
p => p.Tasks
.Where(t => t.Id == taskGuid)
.Include(t => t.Name))
);
ctx.ExecuteQuery();
我的问题出在这部分 .Where(t => t.Id == taskGuid)
。如果我只想加载 1 个任务,它应该如何工作,但如果我想加载一个以上的任务,它就不会工作。当然我可以这样写 .Where(t => t.Id == taskGuid1 || t.Id == taskGuid2 || ... )
但这不是动态的。
我尝试的是使用数组并查看数组是否 GuidArray.Contains(p.Id)
但是,如果我尝试在 Where()
表达式中使用 .Contains()
,则会出现错误。
ClientRequestException: The 'Contains' member cannot be used in the expression.
所以我在想是否可以根据我要加载的任务数以某种方式创建 lambda 表达式。
关于 lambda 的创建,您可以像这样创建您正在寻找的动态或条件
public static class ExpressionExt
{
public static IQueryable<T> Where<T,TKey>(this IQueryable<T> data, string prop,params TKey[] guids)
{
var param = Expression.Parameter(typeof(T));
var exp = guids.Select(g => Expression.Equal(Expression.Property(param, prop), Expression.Constant(g))).Aggregate((a, e) => a != null ? Expression.Or(e, a) : e);
var lambda = Expression.Lambda<Func<T, bool>>(exp, param);
return data.Where(lambda);
}
}
并像 Where(nameof(A.Id), guids)
一样使用它 这是我通常在 IQueryable 仅支持或不包含时所做的事情。那里可能有一个包含实现,因此您可能需要查看文档。
简而言之,我想要完成的是使用 CSOM 从 SharePoint Project Server 中的项目加载任务。
var projects = ctx.LoadQuery(ctx.Projects
.Where(p => p.Id == projGuid)
.Include(
p => p.Id, p => p.Name,
p => p.Tasks
.Where(t => t.Id == taskGuid)
.Include(t => t.Name))
);
ctx.ExecuteQuery();
我的问题出在这部分 .Where(t => t.Id == taskGuid)
。如果我只想加载 1 个任务,它应该如何工作,但如果我想加载一个以上的任务,它就不会工作。当然我可以这样写 .Where(t => t.Id == taskGuid1 || t.Id == taskGuid2 || ... )
但这不是动态的。
我尝试的是使用数组并查看数组是否 GuidArray.Contains(p.Id)
但是,如果我尝试在 Where()
表达式中使用 .Contains()
,则会出现错误。
ClientRequestException: The 'Contains' member cannot be used in the expression.
所以我在想是否可以根据我要加载的任务数以某种方式创建 lambda 表达式。
关于 lambda 的创建,您可以像这样创建您正在寻找的动态或条件
public static class ExpressionExt
{
public static IQueryable<T> Where<T,TKey>(this IQueryable<T> data, string prop,params TKey[] guids)
{
var param = Expression.Parameter(typeof(T));
var exp = guids.Select(g => Expression.Equal(Expression.Property(param, prop), Expression.Constant(g))).Aggregate((a, e) => a != null ? Expression.Or(e, a) : e);
var lambda = Expression.Lambda<Func<T, bool>>(exp, param);
return data.Where(lambda);
}
}
并像 Where(nameof(A.Id), guids)
一样使用它 这是我通常在 IQueryable 仅支持或不包含时所做的事情。那里可能有一个包含实现,因此您可能需要查看文档。