构建动态Lambda表达式以比较未定义数量的值

时间:2017-12-20 10:30:10

标签: c# lambda csom

简而言之,我想要完成的是使用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)

但如果我尝试在.Contains()表达式中使用Where(),我会收到错误。

  

ClientRequestException:'Contains'成员不能在表达式中使用。

所以我在想是否有可能以某种方式根据我想要加载的任务数创建lambda表达式。

1 个答案:

答案 0 :(得分:1)

我认为创建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仅支持或不包含时通常所做的事情。可能有一个包含实现,因此您可能需要查看文档。