I need to extract the items from a list in reverse order (from last entry to the first). I've managed to get all the items but, from the first to the last. Here is part of the code I am using:
The List is on a different site collection.
using (SPSite oSite = new SPSite("urltolist"))
{
using (SPWeb oWeb = oSite.RootWeb)
{
SPList FItem = oWeb.Lists["List"];
foreach (SPListItem item in FItem.Items)
{
//Display entries
}
}
}
You don't need to dispose of the RootWeb in this case.
using(var site = new SPSite("urltolist"))
{
var list = site.RootWeb.Lists["List"];
foreach(var li in list.Items.Cast<SPListItem>().Reverse().ToList())
{
// Display entries
}
}
Get the SPListItemCollection, then iterate through it in reverse:
var itemCollection = FItem.Items;
for(int i = itemCollection.Count - 1; i >= 0; i--)
{
var item = itemCollection[i];
//Display entries
}
If you just iterate over FItem.Items (i.e. call FItem.Items[i] repeatedly) you end up querying the list repeatedly, so don't do that.
The question you need to ask is what order the items are to begin with - the way you do it, they'll be sorted by ID (analogous to time of creation). If you want to sort them in another way, use an SPQuery with an OrderBy clause to retrieve the list items.
this can also be accomplished with a CAML Query. Do you need to return ALL items? If you can limit the query you can use the CAML node.
Related
So I have this code where I gather the elements then write all the class names to a List then find out the index of that specific class.
This to me seems very longwinded, maybe I should use linq however my brain cannot fathom another way to do it (it is friday!!).
private void Pagination()
{
List<string> classnames = new List<string> { };
var pagination = _driver.FindElements(By.CssSelector("ul[data-type='order-sitebundle']> li"));
//var activepage = _driver.FindElement(By.CssSelector("ul[data-type='order-sitebundle']> li[class='active']"));
foreach (var item in pagination)
{
classnames.Add(item.GetAttribute("className"));
}
int actibve = classnames.IndexOf("active");
pagination[actibve++].Click();
Find the element that is active:
ul[data-type='order-sitebundle'] li[class='active']
You don't have to use actibve++, find the next li after the active one:
ul[data-type='order-sitebundle'] li[class='active'] + li
I am trying to get some Sitecore items and then sort them by their creation date with newest items first.
I have the following code (snippet):
itemID = Constants.BucketIds.NEWS;
Item pressItem = context.GetItem(itemID);
var pressChildItems = context
.SelectItems("/sitecore/content" + pressItem.Paths.ContentPath + "/*")
.OrderByDescending(x => x.Fields[Sitecore.FieldIDs.Created]);
foreach (Item childItem in pressChildItems)
{
// DO SOMETHING
}
I am getting the following error back:
At least one object must implement IComparable.
I am not sure how I am supposed to fix this.
Do not order by Field, sort by its value. Remove .Fields from your line:
var pressChildItems = context
.SelectItems("/sitecore/content" + pressItem.Paths.ContentPath + "/*")
.OrderByDescending(x => x[Sitecore.FieldIDs.Created]);
Dates are stored as yyyyMMddHHmmss... strings, so sorting by value as string will give you exactly the same effect as getting date value from field and ordering using the date.
Since it looks like you have your items in a Bucket, you should really use the ContentSearch API (and limit the results if you are using them on the front-end since a bucket could potentially contain thousands of items).
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.SearchTypes;
using Sitecore.Data.Items;
List<Item> ResultsItems = new List<Item>();
SitecoreIndexableItem bucket = Context.Database.GetItem(Constants.BucketIds.NEWS);
using (var searchcontext = ContentSearchManager.GetIndex(bucket).CreateSearchContext())
{
IQueryable<SearchResultItem> searchQuery =
searchcontext.GetQueryable<SearchResultItem>()
.OrderByDescending(x => x.CreatedDate)
.Take(10);
SearchResults<SearchResultItem> results = searchQuery.GetResults();
// fetch the Sitecore Items if you do not want to work with the SearchResultItem
foreach (var hit in results.Hits)
{
Item item = hit.Document.GetItem();
if (item != null)
{
ResultsItems.Add(item);
}
}
}
I need to create a view for all the lists. The view has to show the fields that are mandatory (is different in every list).
It all goes wrong when the second list is retrieved. The first for-each gives the following error message:
Collection was modified; enumeration operation may not execute
I really don't know why I get this bug.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb myWeb = SPContext.Current.Web;
SPListCollection myLists = myWeb.GetListsOfType(SPBaseType.DocumentLibrary);
StringCollection viewFields = new StringCollection();
String viewName = "Mandatory fields view";
String query = "<OrderBy><FieldRef Name='Modified'/></OrderBy><Where><Eq><FieldRef Name='Author'/><Value Type='Integer'><UserID Type='Integer' /></Value></Eq></Where>";
foreach (SPList list in myLists)
{
foreach (SPField field in list.Fields)
{
if (field.Required)
{
viewFields.Add(field.ToString());
}
}
list.Views.Add(viewName, viewFields, query, Int32.MaxValue, true, false);
viewFields.Clear();
}
}
Or you could just use a for loop instead of a foreach:
for(int i = 0; i< myLists.Count; i++){
SPList list = myLists[i];
//etc..
}
Try changing foreach (SPList list in myLists) to foreach (SPList list in myLists.ToList()). This will copy the values of myLists to a separate list that can not be modified during each foreach loop.
I have a function which searches some articles in the Sitecore content items and give me the value. So far I have build up my indexes and it is showing in my IndexViewer. But the return of the function is 0. I looked up this link: http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html for more information.
protected IEnumerable<Item> ShowHomePageNews(int numOfArticles, string stringofCountries)
{
List<Item> items = new List<Item>();
Sitecore.Search.Index indx = SearchManager.GetIndex("newsArticles");
using (IndexSearchContext searchContext = indx.CreateSearchContext())
{
var db = Sitecore.Context.Database;
CombinedQuery query = new CombinedQuery();
QueryBase catQuery = new FieldQuery("countries", stringofCountries); //FieldName, FieldValue.
SearchHits results = searchContext.Search(catQuery); //Searching the content items by fields.
SearchResultCollection result = results.FetchResults(0, numOfArticles);
foreach (SearchResult i in result)
{
items = result
.Where(r => !r.Title.StartsWith("*"))
.Select(r => db.GetItem(new Sitecore.Data.ItemUri(r.Url).ToDataUri()))
.ToList();
//Lucene.Net.Documents.Field url = i.Document.GetField("_url");
//Sitecore.Data.ItemUri itemUri = new Sitecore.Data.ItemUri(url.StringValue());
//Sitecore.Data.Items.Item item = Sitecore.Context.Database.GetItem(itemUri.ToDataUri());
//items.Add(item);
}
}
return items;
}
Over here the result is 0. What I am doing wrond here?
This is the snapshot of what I am seeing in my IndexViewer:
EDIT:
I am passing a "NZ" in the 'catQuery' and I am getting the result back. Because in my index viewer I am seeing the Field Name = _name, which contains NZ in it. I got this part. However, I want my every field to be indexed. I am seeing only 3 fields in my IndexViewer: _url, _group & _name.
So your countries should be tokenized by the indexer. As a multilist, they will be tokenized by GUID. Searching for a single country by GUID with your code above should work. However, if you want to search for multiple countries, where any of the passed in countries can trigger a match, you need to structure your query differently.
CombinedQuery query = new CombinedQuery();
//apply other filters here to query if need be
//and country filter by creating a new clause (combinedquery) and "ORing" within it (QueryOccurance.Should)
CombinedQuery query3 = new CombinedQuery();
//here you would actually iterate over your country list
query3.Add(new FieldQuery("countries", country1GUID), QueryOccurance.Should);
query3.Add(new FieldQuery("countries", country2GUID), QueryOccurance.Should);
query.Add(query3, QueryOccurance.Must);
I have my source list data in the sourceList data table and want to copy that data to its root list.
How can I do that?
private void MoveToTopTaskList(DataTable sourceList, SPSite DestinationSiteCollection)
{
SPWeb Destinationsite = DestinationSiteCollection.OpenWeb();
SPList DestinationList = Destinationsite.Lists[TASKS];
SPListItem DestinationListItem = DestinationList.Items.Add();
foreach (DataRow row in sourceList.Rows)
{
}
}
Best Approach for the above case is to Use the ProcessBatchData Method of the SPWeb Object. This will help you to update List items in to the List in Batch.
You need to build an XML tags that will have details for inserting the data to the list.
If you have large number of records to be inserted to the list consider spliting it in to smaller batchs. Say if you have 1000 records do it in two 500 sets.
While building the XML make sure you use StringBuilder class to append the string.
Refer these Links [Link1][1] [Link2][2] [Link3][3] for more information on ProcessBatchData
In case if you want to do it using the OM. Then follow code
`SPWeb Destinationsite = DestinationSiteCollection.OpenWeb();
SPList DestinationList = Destinationsite.Lists[TASKS];
SPListItem DestinationListItem = DestinationList.Items.Add();
foreach (DataRow row in sourceList.Rows)
{
DestinationListItem = DestinationList.Items.Add();
DestinationListItem["Field1"]=row["Col"].ToString();
DestinationListItem["Fieldn"]=row["Coln"].ToString();
DestinationListItem.Update()
}
`
[1]:https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-services/cc404818%28v=office.12%29
[2]:http://www.sharepointblogs.com/smc750/archive/2008/04/03/spweb-processbatchdata-a-list-is-a-list-is-a-list.aspx
[3]:https://web.archive.org/web/20121029142042/http://blog.dynatrace.com:80/2009/01/20/sharepoint-using-batch-updates-to-speed-up-performance/