The collection has not been initialized - c#

I am trying to retrieve all items from a Sharepoint library with CSOM and create a list of it. I am sure it has something to do with the order of the code. The question is how?
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(collListItem);
context.ExecuteQuery();
foreach (var col in items)
{
newList.Add(new Item()
{
ID = Convert.ToInt32(col["ID"]),
});
}
I get the following error:
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested

You should have loaded the items object not the collListItems thus your code should look following:
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(items);
context.ExecuteQuery();

I have a same problem, then I recalled ExecuteQuery() below foreach loop and that worked for me
ListItemCollection recruitmentItems= Recuitment.GetItems(camlQuery);
cc.Load(recruitmentItems, items => items.Include(
x => x.Id,
x => x["Title"],
x => x["Email"],
x => x["Phone"]
));
cc.ExecuteQuery();
foreach (ListItem item in recruitmentItems)
{
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = Applicant.AddItem(itemCreateInfo);
newItem["Title"] = item["Title"];
newItem["Email"] = item["Email"];
newItem["PhoneNumber"] = item["Phone"];
newItem.Update();
}
cc.ExecuteQuery();

Related

Access items in list pertaining to GroupBy() item

I am instantiating a List, derived from an ObservableCollection:
var paidTrips = PaidTrips
.GroupBy(p => new {p.LicenseHolderID})
.ToList();
Which, through a foreach loop, gives me access to the various distinct values in LicenseHolderID.
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
// but no access to the other items
}
What I need help with:
How can I obtain access to the other items in paidTrips, which pertain to LicenseHolderID? (Why: I am creating invoices, one per LicenseHolderID, and I am building the invoice with the data from all the other collection properties).
To give some context, here's the full collection I am working with:
PaidTrips.Add(new PaidTrip {
LicenseHolderID = dr[0].ToString(),
VehicleID = dr[1].ToString(),
Year = dr[2].ToString(),
Month = dr[3].ToString(),
Payment = (decimal)dr[4],
PaymentNet = (decimal)dr[5],
OrderFee = (decimal)dr[6],
PaymentFee = (decimal)dr[7],
TripVATcode = (decimal)dr[8],
LicenseHolderInvoiceID = dr[9].ToString(),
TripFeeNet = (decimal)dr[10],
TripFeeVATcode = (decimal)dr[11],
RidelRegionInvoiceID = dr[12].ToString(),
});
It does depend what your looking to do with the data for each invoice? are you looking to summarise the data within each LicenseHolderID group?
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
//ie here total payment (This sums all payments for this LicenseHolderID)
var totalPayment = group.Sum(x => x.Payment)
// count of payments made (This Counts all Payments greater than 0)
var totalPayments = group.Count(x => x.Payment > 0)
//Use variables in your invoice generation
}
or as above iterate through each group item and access it in singular form.
If I understand you correctly, you want to access each group member's property. To achieve this, you should use nested foreach to traverse each group and access its members.
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
foreach (var paidTrip in group.ToList())
{
Console.WriteLine(paidTrip.TripFeeNet);
}
}
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
if (licenseHolder.Key == desiredLicenseHolderID){
foreach (var paidItem in licenseHolder){
paidItem.VehicleID = .......
}
}
}
The .GrouBy() Returns a IGrouping object which contains the Key and the elements grouped by the key. To access the elements of the Key grouping you are after once you iterated through the items and found the one, you can simply iterate through the item as an array.

Unable to update "Last_x0020_Modified" in a SharePoint document

I would like to update "Last_x0020_Modified" in the SharePoint documentation.
I am unable to update with the error.
"Invalid data is being used to update the list item. The field you are trying to update may be read-only."
Is there a way to update "Last_x0020_Modified"?
using (var context = new ClientContext("URL"))
{
var passWord = new SecureString();
foreach (char c in "pass".ToCharArray())
{
passWord.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials("account", passWord);
var documents = context.Web.Lists.GetByTitle("Document");
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = false;
documents.Update();
context.ExecuteQuery();
var query = CamlQuery.CreateAllItemsQuery();
var collListItem = documents.GetItems(query);
context.Load(collListItem,
items => items.Include(
item => item.Id,
item => item.DisplayName,
item => item.ContentType,
item => item["Modified"],
item => item["Last_x0020_Modified"]
));
context.ExecuteQuery();
foreach (var listItem in collListItem.Where(item => item.ContentType.Name == "folder"))
{
listItem["Last_x0020_Modified"] = "2020/09/01T09:00:00";
}
context.ExecuteQuery();
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = true;
documents.Update();
context.ExecuteQuery();
}
Best Regard.
Per my test, I got the same result as yours on my end. Looks like we cannot change the property "Last_x0020_Modified".
Besides, I found the field "Last_x0020_Modified" is a lookup field.

Create c# lambda expression in a loop

How can I convert the following lambda expression for running a SharePoint query in CSOM to accept an array of parameters:
Current working version:
var listItems = list.GetItems(query);
clientContext.Load(listItems,
items => items.Include(
item => item["Title"],
item => item.RoleAssignments
)
);
clientContext.Load(list, l => l.Id, l => l.DefaultDisplayFormUrl);
clientContext.ExecuteQuery();
How I would like it to work:
var fields = new List<string>()
{
"Title",
"ID",
"DocumentOrder",
"FileRef"
};
var listItems = list.GetItems(query);
clientContext.Load(listItems,
items => items.Include(
item => fields,
item => item.RoleAssignments
)
);
clientContext.Load(list, l => l.Id, l => l.DefaultDisplayFormUrl);
clientContext.ExecuteQuery();
This throws an error, is it possible to pass in a dynamic list?
Though not ideal, I have been able to achieve what I am attempting to do by calling Load several times in a loop:
var fieldNames = new List<string>()
{
"Title",
"ID",
"DocumentOrder",
"FileRef"
};
var listItems = list.GetItems(query);
foreach (var fieldName in fieldNames)
{
clientContext.Load(listItems,
items => items.Include(
item => item[fieldName]
)
);
}
clientContext.ExecuteQuery();

Populating RadMenu Dynamically from Code Behind

I am trying to dynamically populate a Telerik Radmenu control in my code behind. I'm having a really hard time with it. I need to be able to bind my categories to my root elements and attributes to the child elements. I really am lost on this. If even someone has a suggestion of a better way to do this, even if it's with a different type of menu I would be very happy to try it out. Thanks in advance.
**EDIT my code has changed.
protected void createFilter(int categoryid)
{
// check cateogyrid
//get list of proudct id
List<int> productIds = new List<int>();
DataRow[] productRow = CategoriesProductsData.Tables["Products"].Select("Category_ID = " + 573);
productIds = productRow.Select(p => int.Parse(p["Product_ID"].ToString())).ToList();
//get attributes
ITCProductService pService = new TCProductServiceClient();
var productTuples = (pService.GetProductsAttributes(productIds));
List<Tuple<int, CustomAttribute>> customAttributes = new List<Tuple<int, CustomAttribute>>();
foreach (var productTuple in productTuples)
{
foreach (var attributeTuple in productTuple.m_Item2)
{
var customAttribute = new Tuple<int, CustomAttribute>(productTuple.m_Item1, new CustomAttribute(attributeTuple));
customAttributes.Add(customAttribute);
}
}
List<CustomAttributeCategory> categories = new List<CustomAttributeCategory>();
var categoryTuples = customAttributes.Select(a => a.Item2).Select(a => a.Attribute.Category).Distinct();
foreach (var categoryTuple in categoryTuples)
{
var category = new CustomAttributeCategory(categoryTuple);
var attributeByCategory = customAttributes.Select(a => a.Item2).Where(b => b.Attribute.CategoryId == categoryTuple.AttributeCategoryId).Distinct();
foreach (var attributeTuple in attributeByCategory)
{
var attribute = new CustomAttribute(attributeTuple.Attribute);
var attributeProductIds = customAttributes.Where(a => a.Item2.Attribute.AttributeId == attributeTuple.Attribute.AttributeId).Select(a => a.Item1).ToList();
attribute.ProductIds = attributeProductIds;
category.Attributes.Add(attribute);
}
categories.Add(category);
foreach (var cat in categories)
{
var itemCategory = new RadMenuItem(cat.Category.Name.ToString());
handsetMenu.Items.Add(itemCategory);
var itemAttribute = new RadMenuItem(cat.Attributes.ToString());
handsetMenu.Items.Add(itemAttribute);
}
}
}
<%--RAD MENU--%>
<telerik:RadMenu ID="handsetMenu" runat="server" ShowToggleHandle="true">
</telerik:RadMenu>
I don't think ItemDataBound is the correct place to add child items.
Do you want to add the same child items under each of the root menu items?
Try doing it in the DataBound event (which fires after all itemDataBound events have completed) by iterating all RadMenu items.

querying existing ListView items with LINQ

The ListView I have populates through these loops resulting in four columns being filled
// Create a ResXResourceReader
ResXResourceReader rdr0 = new ResXResourceReader(textPath1.Text + ".resx");
ResXResourceReader rdr1 = new ResXResourceReader(textPath1.Text + ".es.resx");
ResXResourceReader rdr2 = new ResXResourceReader(textPath1.Text + ".fr.resx");
foreach (DictionaryEntry d in rdr0)
{
TransResource x = new TransResource();
x.id = d.Key.ToString();
x.en = d.Value.ToString();
resources.Add(x.id, x);
}
foreach (DictionaryEntry d in rdr1)
{
TransResource x = resources[d.Key.ToString()];
x.fr = d.Value.ToString();
}
foreach (DictionaryEntry d in rdr2)
{
TransResource x = resources[d.Key.ToString()];
x.es = d.Value.ToString();
}
foreach (TransResource x in resources.Values)
{
string[] row = { x.id, x.en, x.fr, x.es };
var listViewItem = new ListViewItem(row);
listResx.Items.Add(listViewItem);
}
What I want to do is query all of the results in this ListView against what is entered in textboxQuery. If any field in the entire listview contains the string from textboxQuery I want it to be displayed in a new listview (lets say listviewQueryresult). I've had many failed attempts at this but I know it is possible through LINQ.
Because ListView.Items implements IEnumerable, but does not implement IEnumerable<T> you have to cast it to IEnumerable<ListViewItem> first, to query it using LINQ to Objects:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => YourPredicate(x));
If any field in the entire listview contains the string from
textboxQuery I want it to then be displayed in a new listview (lets
say listviewQueryresult)
For that, the predicate would be just:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => x.Text.Contains(textboxQuery));

Categories

Resources