【问题标题】:Build dynamic Lambda Expression for comparing undefined number of values构建动态 Lambda 表达式以比较未定义数量的值
【发布时间】:2017-12-20 10:30:10
【问题描述】:

简而言之,我想要完成的是使用 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: 'Contains' 成员不能在表达式中使用。

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

【问题讨论】:

  • 你可以使用 FirstOrDefault() 并检查不为空吗?或者你可以使用 Any() 吗?
  • 这取决于你的数据库的性能有多好,但如果它很快,你可以用 ID 构建一个数组并循环遍历它。

标签: c# lambda csom


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多