How to copy a DataTable to a SharePoint SPList? - c#

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/

Related

Find within large list using Contains within Linq

I have two large excel files. I am able to get the rows of these excel files into a list using linqtoexcel. The issue is that I need to use a string from one object within the first list to find if it is part of or contained inside another string within an object of the second list. I was trying the following but the process is taking to long as each list is over 70,000 items.
I have tried using an Any statement but have not be able to pull results. If you have any ideas please share.
List<ExcelOne> exOne = new List<ExcelOne>();
List<ExcelTwo> exTwo = new List<ExcelTwo>();
I am able to build the first list and second list and can verify there are objects in the list. Here was my thought of how I would work through the lists to find matching. Note that once I have found the matching I want to create a new class and add it to a new list.
List<NewFormRow> rows = new List<NewFormRow>();
foreach (var item in exOne)
{
//I am going through each item in list one
foreach (var thing in exTwo)
{
//I now want to check if exTwo.importantRow has or
//contains any part of the string from item.id
if (thing.importantRow.Contains(item.id))
{
NewFormRow adding = new NewFormRow()
{
Idfound = item.id,
ImportantRow = thing.importantRow
};
rows.Add(adding);
Console.WriteLine("added one");
}
}
If you know a quicker way around this please share. Thank you.
It's hard to improve this substring approach. The question is if you have to do it here. Can't you do it where you have filled the lists? Then you don't need this additional step.
However, maybe you find this LINQ query more readable:
List<NewFormRow> rows = exOne
.SelectMany(x => exTwo
.Where(x2 => x2.importantRow.Contains(x.id))
.Select(x2 => new NewFormRow
{
Idfound = x.id,
ImportantRow = x2.importantRow
}))
.ToList();

I'm using the property findelements with selenium and C#, but it keeps giving the same error

This is a part of the code that i was trying to use to get the respective elements, but it keeps giving me the following error:
System.Collections.ObjectModel.ReadOnlyCollection`1[OpenQA.Selenium.IWebElement]or
others identical
This is also shown in a datagridview, in her rows.
IList<IWebElement> ruas = Gdriver.FindElements(By.ClassName("search-title"));
String[] AllText = new String[ruas.Count];
int i = 0;
foreach (IWebElement element in ruas)
{
AllText[i++] = element.Text;
table.Rows.Add(ruas);
}
First thing is: as far as I understand the elements you are talking about are not contained in table. Its a list: <ul class="list-unstyled list-inline">... (considering the comment you left with site link)
If you want to find those elements you can use the code below:
var elements = driver.FindElements(By.CssSelector("ul.list-inline > li > a"));
// Here you can iterate though links and do whatever you want with them
foreach (var element in elements)
{
Console.WriteLine(element.Text);
}
// Here is the collection of links texts
var linkNames = elements.Select(e => e.Text).ToList();
Considering the error you get, I may assume that you are using DataGridView for storing collected data, which is terribly incorrect. DataGridView is used for viewing data in MVC application. There is no standard Selenium class for storing table data. There are multiple approaches for this, but I can't suggest you any because I don't know your what you are trying to achieve.
Here is how i answered my own question:
IList<string> all = new List<string>();
foreach (var element in Gdriver.FindElements(By.ClassName("search-title")))
{
all.Add(element.Text);
table.Rows.Add(element.Text);
}

How to convert a list of objects to a list of strings in c#?

I have a List where GetData is a class. My requirement is to get all the rows of a column and add a prefix "Week" to it in order to get the data in JSON format for kendo charts.
Here is my code,
foreach (DataRow dr in dt.Rows)
{
lstweeks = new List<GetData>()
{
new GetData{week = dr["WK"].ToString()}
};
var item = lstweeks.ToList();
lst1.Add(item.ToString());
lstweeks.Clear();
}
The result of lstweeks is : {"week":"42", "week":"43", "week":"44"}
I want to add this to another list of strings (lst1) so that I can concat lst1 with other string values. But when I try to add lstweeks to lst1, I get this result:
["System.Collections.Generic.List`1[WcfService1.GetData]",
"System.Collections.Generic.List`1[WcfService1.GetData]",
"System.Collections.Generic.List`1[WcfService1.GetData]",
"System.Collections.Generic.List`1[WcfService1.GetData]",
"System.Collections.Generic.List`1[WcfService1.GetData]"]
How can I convert my lstweeks to list of strings lst1.
P.S. I tried defining the List (lst1) as List, in that case, I get the following result in the browser.
Let me know how can I solve this issue. Any help would be appreciated.
Thanks.
I got the answer. It was very simple.
Updated code,
foreach (DataRow dr in dt.Rows)
{
lstweeks.Add(
{
new GetData{week = dr["WK"].ToString()}
);
}

reverse an SPlist

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.

Query - row based table

I have no control over how the data is saved in this table. However, I have to query the table and combine the data for similar pn_id column as one row/record.
For instance current data structure is as follows,
Here we have same pn_id repeated with different question ids. This should have been really saved as one pn_id and then each question as a separate column, per my opinion. However, I have to retrieve the below data as one record like this this..
Any idea how this can be done?
Thanks
Here's some pseudocode for the transform algorithm. Note that it requires scanning the entire data set twice; there are a few other opportunities to improve the efficiency, for example, if the input data can be sorted. Also, since it's pseudocode, I haven't added handling for null values.
var columnNames = new HashSet<string> { "pn_id" };
foreach (var record in data)
columnNames.Add(record.question_id.ToString());
var table = new DataTable();
foreach (var name in columnNames)
table.Columns.Add(new DataColumn(name, typeof(string)));
foreach (var record in data)
{
var targetRecord = CreateNewOrGetExistingRecord(table, record.pn_id);
targetRecord[record.question_id.ToString()] = record.char_value ?? record.date_value.ToString();
}
And here's a sketch of the helper method:
DataRow CreateNewOrGetExistingRecord(DataTable table, object primaryKeyValue)
{
var result = table.Find(primaryKeyValue);
if (result != null)
return result;
//add code here to create a new row, add it to the table, and return it to the caller
}
the structure is fine. Wouldn't make sense to have one columns per question because you would have to add a new column every time a new question were added.
Your problem can easily be solved with PIVOT. Take a look at this link for explanation

Categories

Resources