构建动态 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 仅支持或不包含时所做的事情。那里可能有一个包含实现,因此您可能需要查看文档。