2009-02-18 14 views
15

Mam listę, która wygląda tak:Jaki jest najlepszy sposób na uzyskanie różnych/unikalnych wartości za pomocą dodatku SPQuery?

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

Korzystanie Caml a obiekt SPQuery muszę się odrębną listę elementów z kolumny roku, który będzie wypełnić rozwijanej kontrolą.

Wyszukiwanie w tym miejscu nie wydaje się być sposobem na wykonanie tego zapytania CAML. Zastanawiam się, jak ludzie osiągnęli ten cel?

Odpowiedz

13

Innym sposobem, aby to zrobić jest użycie DataView.ToTable-method - jego pierwszy parametr to taka, która sprawia, że ​​lista odrębne.

  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); 

Następnie można kontynuować przy użyciu DataTable tbl.

+2

Chociaż ten został oznaczony jako odpowiedź, metoda ta polega na pobraniu nadal każdy element listy z bazy danych, a następnie * * znalezienie unikalne wartości. Wydaje mi się, że pytaniem, jak to zrobić w CAML, jest unikanie pobierania każdego elementu z bazy danych ... – MgSam

+2

Zgadzam się z MgSam, ponieważ CAML nie jest prawdziwym zamiennikiem rzeczywistego języka zapytań takiego jak SQL. To jest tak dobre, jak to tylko możliwe. Ta odpowiedź przesuwa rozmowę do przodu. +1 ode mnie. –

2

Nie ma DISTINCT w CAML, aby wypełnić swoją rozwijana spróbuj coś takiego:

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); 
     } 
    } 

zakłada swoją rozwijana jest nazywany ddlYear.

1

Czy można przejść z SPQuery do SPSiteDataQuery? Powinieneś być w stanie, bez żadnych problemów.

Po tym, można użyć standardowego zachowania 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"); 
5

Jeśli chcesz powiązać różne wyniki z DataSource na przykład z Repeater i zachować rzeczywisty przedmiot za pomocą metody "e.Item.DataItem" ItemDataBound, sposób DataTable nie będzie działać. Zamiast tego, a ponadto, gdy nie chce się powiązać go z DataSource, można również użyć Linq do zdefiniowania odrębnych wartości.

// 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(); 

Pamiętaj, że ponieważ nie ma wsparcia CAML dla różnych zapytań, każda próbka umieszczonych na tej stronie będzie pobierać wszystkie elementy z SPList. Może to być dobre dla mniejszych list, ale dla list z tysiącami listitem, będzie to poważnie zabójca wydajności. Niestety nie ma bardziej zoptymalizowanego sposobu osiągnięcia tego samego.

0

I rozważa ten problem wcześniej dzisiaj, a najlepszym rozwiązaniem mogłoby myślę wykorzystuje następujący algorytm (przepraszam, brak kodu w tej chwili):

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 

To zmniejszenie całkowitej liczby pozycji zwracanych znacznie, kosztem większej liczby zapytań.

Nie ma znaczenia, czy X jest całkowicie dokładne, ale losowość jest dość ważna. Zasadniczo pierwsza kwerenda prawdopodobnie zawiera najbardziej powszechne opcje, więc drugie zapytanie wyklucza je i prawdopodobnie zawiera kolejne najczęstsze opcje itd. Poprzez iteracje.

W najlepszym przypadku pierwsze zapytanie zawiera wszystkie opcje, a drugie zapytanie będzie puste. (X pozycji pobranych łącznie, ponad 2 zapytania)

W najgorszym przypadku (np. Zapytanie jest sortowane według szukanych opcji, a dla każdej opcji jest więcej niż X pozycji) zrobimy jako wiele zapytań, ponieważ są opcje. Zwracam łącznie około X * X elementów.

0

Po przeczytaniu posta po tym, jak to było niemożliwe, w końcu znalazłem sposób. Zostało to przetestowane w usłudze SharePoint Online. Oto funkcja, która pozwoli uzyskać wszystkie unikalne wartości dla kolumny. Wymaga jedynie podania ID listy, Id widoku, nazwy listy wewnętrznej i funkcji wywołania zwrotnego.

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"); 
}); 

}

Powiązane problemy