15

我有一个看起来像的列表:

Movie          Year
-----          ----
Fight Club     1999
The Matrix     1999
Pulp Fiction   1994

使用 CAML 和 SPQuery 对象,我需要从 Year 列中获取不同的项目列表,该列表将填充下拉控件。

在 CAML 查询中搜索似乎不是一种方法。我想知道人们是如何实现这一目标的?

4

6 回答 6

13

另一种方法是使用 DataView.ToTable-Method - 它的第一个参数是使列表不同的参数。

            SPList movies = SPContext.Current.Web.Lists["Movies"];
            SPQuery query = new SPQuery();
            query.Query = "<OrderBy><FieldRef Name='Year' /></OrderBy>";

            DataTable tempTbl = movies.GetItems(query).GetDataTable();
            DataView v = new DataView(tempTbl);
            String[] columns = {"Year"};
            DataTable tbl = v.ToTable(true, columns);

然后,您可以继续使用 DataTable tbl。

于 2009-02-18T16:35:07.183 回答
5

如果您想将不同的结果绑定到例如 Repeater 的 DataSource 并通过 ItemDataBound 事件的 e.Item.DataItem 方法保留实际项目,则 DataTable 方式将不起作用。相反,除了不想将其绑定到 DataSource 时,您还可以使用 Linq 来定义不同的值。

// Retrieve the list. NEVER use the Web.Lists["Movies"] option as in the other examples as this will enumerate every list in your SPWeb and may cause serious performance issues
var list = SPContext.Current.Web.Lists.TryGetList("Movies");

// Make sure the list was successfully retrieved
if(list == null) return;

// Retrieve all items in the list
var items = list.GetItems();

// Filter the items in the results to only retain distinct items in an 2D array
var distinctItems = (from SPListItem item in items select item["Year"]).Distinct().ToArray()

// Bind results to the repeater
Repeater.DataSource = distinctItems;
Repeater.DataBind();

请记住,由于 CAML 不支持不同的查询,因此此页面上提供的每个示例都将从 SPList 中检索所有项目。这对于较小的列表可能很好,但对于具有数千个列表项的列表,这将严重影响性能。不幸的是,没有更优化的方法可以达到同样的效果。

于 2010-12-29T10:25:15.357 回答
2

CAML 中没有 DISTINCT 来填充您的下拉列表,请尝试使用以下内容:

foreach (SPListItem listItem in listItems)
    {
        if ( null == ddlYear.Items.FindByText(listItem["Year"].ToString()) )
       {
                   ListItem ThisItem = new ListItem();
                   ThisItem.Text = listItem["Year"].ToString();
                   ThisItem.Value = listItem["Year"].ToString();
                   ddlYear.Items.Add(ThisItem);
        }
   }

假设您的下拉列表称为 ddlYear。

于 2009-02-18T11:05:40.313 回答
1

您可以从 SPQuery 切换到 SPSiteDataQuery 吗?你应该可以,没有任何问题。

之后,您可以使用标准的 ado.net 行为:

SPSiteDataQuery query = new SPSiteDataQuery();
/// ... populate your query here. Make sure you add Year to the ViewFields.

DataTable table = SPContext.Current.Web.GetSiteData(query);

//create a new dataview for our table
DataView view = new DataView(table);

//and finally create a new datatable with unique values on the columns specified

DataTable tableUnique = view.ToTable(true, "Year");
于 2009-02-18T16:29:08.803 回答
1

在一次又一次地遇到关于这是不可能的帖子之后,我终于找到了一种方法。这已在 SharePoint Online 中进行了测试。这是一个可以为您获取列的所有唯一值的函数。它只需要您传入列表 ID、视图 ID、内部列表名称和回调函数。

function getUniqueColumnValues(listid, viewid, column,  _callback){
var uniqueVals = [];
$.ajax({
    url: _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/filter.aspx?ListId={" + listid + "}&FieldInternalName=" + column + "&ViewId={" + viewid + "}&FilterOnly=1&Filter=1",
    method: "GET",
    headers: { "Accept": "application/json; odata=verbose" }
    }).then(function(response) {
        $(response).find('OPTION').each(function(a,b){
            if ($(b)[0].value) {
                uniqueVals.push($(b)[0].value);
            }
        });
        _callback(true,uniqueVals);
},function(){
    _callback(false,"Error retrieving unique column values");
});

}

于 2017-08-30T20:17:38.930 回答
0

我今天早些时候正在考虑这个问题,我能想到的最佳解决方案使用以下算法(抱歉,目前没有代码):

L is a list of known values (starts populated with the static Choice options when querying fill-in options, for example)
X is approximately the number of possible options

1. Create a query that excludes the items in L
1. Use the query to fetch X items from list (ordered as randomly as possible)
2. Add unique items to L
3. Repeat 1 - 3 until number of fetched items < X

这将显着减少返回的项目总数,但代价是进行更多查询。

X 是否完全准确并不重要,但随机性非常重要。本质上,第一个查询可能包含最常见的选项,因此第二个查询将排除这些选项,并可能包含下一个最常见的选项,依此类推。

在最好的情况下,第一个查询包含所有选项,那么第二个查询将为空。(共检索 X 项,超过 2 个查询)

在最坏的情况下(例如,查询是按我们正在寻找的选项排序的,并且每个选项有超过 X 项),我们将进行与选项一样多的查询。总共返回大约 X * X 个项目。

于 2012-11-23T21:08:01.050 回答