C# 如何从SharePoint CSOM查询中仅获取唯一字段值?

C# 如何从SharePoint CSOM查询中仅获取唯一字段值?,c#,linq,csom,C#,Linq,Csom,我正在使用SharePoint客户端对象模型从SharePoint 2013列表检索数据。以下代码起作用,并从keyCol列表字段中正确排序获取所有值: string keyCol = "SPFieldName"; CamlQuery keyColumnValuesQuery = CamlQuery.CreateAllItemsQuery(); ListItemCollection keyColumnValues = srcDocLib.GetItems(keyColumnValuesQuery

我正在使用SharePoint客户端对象模型从SharePoint 2013列表检索数据。以下代码起作用,并从keyCol列表字段中正确排序获取所有值:

string keyCol = "SPFieldName";
CamlQuery keyColumnValuesQuery = CamlQuery.CreateAllItemsQuery();
ListItemCollection keyColumnValues = srcDocLib.GetItems(keyColumnValuesQuery);
spContext.Load(keyColumnValues, items => items.Include(item => item[keyCol]), items => items.OrderBy(item => item[keyCol]));
spContext.ExecuteQuery();
但是,我只想为字段中的每个唯一值检索一个项,即一个独特的值。将Distinct()Linq/Lambda添加到Load method retrievals参数时(无编译时问题):

我得到一个InvalidQueryExpressionException:不支持查询表达式“items.Distinct()”


这是否意味着SharePoint端的Linq提供程序不支持该表达式,而我使用这种技术只是运气不佳?我做错什么了吗?谢谢。

用于SharePoint的Linq提供程序不支持
Distinct
运算符

根据MSDN:

有些LINQ查询无法完全转换为CAML。然而, 但是,原则上,这样的查询可以正确运行,因为它们可以 分两个阶段执行。首先,LINQ到SharePoint提供商 将尽可能多的查询转换为CAML并执行 质疑

有关更多详细信息,请参阅

两阶段法 要更正此错误,您应该将查询分为两个阶段,以强制在第二个阶段之前执行第一个查询。为此,您应该使用
ToList()
方法变换列表中的第一个
IEnumerable

以下示例演示如何返回唯一值:

   //1 Execute query against SP Linq provider   
    string keyCol = "SPFieldName";
    CamlQuery keyColumnValuesQuery = CamlQuery.CreateAllItemsQuery();
    ListItemCollection keyColumnValues = srcDocLib.GetItems(keyColumnValuesQuery);
    spContext.Load(keyColumnValues, items => items.Include(item => item[keyCol]), items => items.OrderBy(item => item[keyCol]));
    spContext.ExecuteQuery();
    //2. Transform LiItemCollection to a List and perform Distinct operation 
    var uniqueKeyColumnValues = keyColumnValues.ToList().Select(i => i[keyCol]).Distinct(); 

谢谢,这是我一直在寻找的。如果你不介意的话,我想问几个后续问题。乍一看,我以为uniqueKeyColumnValues是列表类型的,但它似乎是列表类型的(实际上对我来说更可取)。代码的Select部分是否从ListItem字段而不是整个ListItem字段中提取字符串值?有一次我尝试了keyColumnValues.ToList().Distinct(),但在重复时得到了相同的结果。这是因为我只给了它一个单独的列表,而不是一系列的值,从这个角度来看,它给我的列表是真正不同的吗?这是正确的,选择操作符提取字段值。例如,如果字段为文本类型,则查询返回列表
   //1 Execute query against SP Linq provider   
    string keyCol = "SPFieldName";
    CamlQuery keyColumnValuesQuery = CamlQuery.CreateAllItemsQuery();
    ListItemCollection keyColumnValues = srcDocLib.GetItems(keyColumnValuesQuery);
    spContext.Load(keyColumnValues, items => items.Include(item => item[keyCol]), items => items.OrderBy(item => item[keyCol]));
    spContext.ExecuteQuery();
    //2. Transform LiItemCollection to a List and perform Distinct operation 
    var uniqueKeyColumnValues = keyColumnValues.ToList().Select(i => i[keyCol]).Distinct();