SharePoint Lookup ListItem not loading value - c#

I am importing a database into SharePoint Lists. I have a list of Plants that are owned by Companies.
Plants have columns for "Plant Name", "Company", "State", "Address", and so on. "Plant Name" and "Address" are both single text lines but "Company" and "State" are lookup types. The "Company" column should look up a name on the "Company" list and link to it. The same for the "State" column linking to the "State" list.
Here is a snippet of my code:
SP.ClientContext context = new SP.ClientContext("http://localhost");
...
newPlantLocation["Company"] = GetItemId(context, "Title", companyName, "Companies");
newPlantLocation["State"] = GetItemId(context, "Title", plantState, "States");
newPlantLocation["Title"] = plantName;
newPlantLocation["Address_x0020_Line_x0020_1"] = plantAddressLine1;
...
newPlantLocation.Update();
and here is the function that returns the ID of the item, it's not the most efficient but easy to follow:
private static int GetItemId(SP.ClientContext context, string columnName, string displayName, string listName)
{
SP.List list = context.Web.Lists.GetByTitle(listName);
SP.CamlQuery query = new SP.CamlQuery();
SP.ListItemCollection items = list.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach (SP.ListItem listItem in items)
{
if (listItem[columnName].Equals(displayName))
{
return listItem.Id;
}
}
return 0;
}
The problem that I'm coming across is that when the importer runs, the plants populate the "Plants" list but the "Company" field is left blank. I'm confused because the "State" field is done pretty much the same way and it somehow ends up populated. I've debugged it and the GetItemId function returns the correct integer of the company, it just isn't showing up or saving to the item.
If I do the following, it all of a sudden starts working:
newPlantLocation["Company"] = 4;

I got it solved now.
It seems that this line, context.ExecuteQuery();, was causing trouble and I was prematurely executing the query before the ListItem was updated.
So I changed my GetItemId function to update the ListItem before doing anything.
private static int GetItemId(SP.ClientContext context, string columnName, string displayName, string listName, SP.ListItem thisItem)
{
thisItem.Update();
//this rest of the code is the same
...
}

Related

How to get all objects inside an array JSON in a C# controller

How do I retrieve all of the [names] that are part of the object called [items] in this JSON scenario below in C# ?
I am using a shopping cart api and want to show the customer all of the items listed off that were part of the order once they get to the thank you page. The parent object I am looking at in the api is called items and it has child object data such as price of each item, name of each item and product image of each item etc.....
In my controller I was doing this below when I only needed to retrieve simple info like the order only has 1 invoiceNumber, 1 payment method, 1 shipping method, 1 promo code etc.. This code below works and gets me that data in that simple scenario below.
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
var obj = JObject.Parse(result);
//Order Info
string invoiceNumber = (string)obj["invoiceNumber"];
string email = (string)obj["email"];
string paymentMethod = (string)obj["paymentMethod"];
string shippingMethod = (string)obj["shippingMethod"];
//Discount info
string amountSaved = (string)obj["discounts"][0]["amountSaved"];
string promoCode = (string)obj["discounts"][0]["code"];
But now I need to tap into an object called [items] (the data for the items that were part of the order) that is going to have many names of items depending on the number of individual items that were part of the customer order. This is what I attempted but then realized that it would only return one record based on what number I used inside the brackets.
string items = (string)obj["items"][0]["name"]; //This returned the product at index 0
string items = (string)obj["items"][1]["name"]; //This returned the product at index 1
string items = (string)obj["items"][2]["name"]; //This returned the product at index 2
How do I write the syntax so that I can grab ALL of the name objects that currently reside in the item object for exaple? I know it has something to do with deserialize objects and list but I do not know the syntax and how to approach.
Any suggestions on how I can get this done?
the simpliest way
List<string> names = obj["items"].Select(x => (string) x["name"] ).ToList();
test
Console.WriteLine( string.Join(",",names)); // prod1,prod2
more complicated way is to create a c# class and deserialize data. But in this case you will be able to use Linq for queries and search
List<Item> items = obj["items"].Select(x => x.ToObject<Item>()).ToList()
public class Item
{
public string name { get; set; }
public double price { get; set; }
public int quantity { get; set; }
}
result (in json format)
[
{
"name": "prod1",
"price": 12.99,
"quantity": 4
},
{
"name": "prod2",
"price": 17.65,
"quantity": 1
}
]
You can use Newtonsoft json package to convert an object into JSON array.
Refer below link
http://www.newtonsoft.com/json/help/html/SerializingJSON.htm

Querying distinct values from NoSQL(Cosmos DB specifically) cannot convert to model type

Summary
In short I am trying to display all the distinct Ids. I am trying to understand why when I first ran my query (not being distinct) I was able to use them with my model as opposed to now. The error that I am getting is Cannot convert from System.String to AppName.Models.Student.
Example
For example displaying all ids from my collection (with repeated ids in documents) : "SELECT s.ClassId from Students s" worked fine, but when I tried to get the distinct values it couldn't convert them, with the query being SELECT DISTINCT VALUE s.ClassId from Students s"
This is my query to Cosmos DB:
public List<T> Query(string query)
{
FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
// Execute query via SQL
IQueryable<T> QueryInSql = Client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(Database, Collection),
$"{query}",
queryOptions);
// convert Iqueryable to a list
return QueryInSql.ToList();
}
I changed my model to just include
public class Class
{
public string ClassId {get; set;}
}
Sample collection with documents
{
{
"id":"abc",
"studentName": "bob",
"classId":"en"
},
{
"id":"bcd",
"studentName": "billy",
"classId":"sp"},
{
"id":"sdf",
"studentName": "bart",
"classId":"en"
}
}
So, the error was in the query I passed in. When adding the VALUE to it, you get back
["en","sp"]
However what I thought I as getting was
[{"id": "en"}, {"id": "sp"}]

How to add Ms-Access database column in any String [] in C#

I am a newbie to C#.
I want to add my one of database's column in string[] but fail to do so. I have created string[] with name "Items" and also create a control with name autocompletemenu1. Now when I type autocompetemenu1.Items = Database Column then the contents of database column should be filled in ITEM string[]. I have tried but it is not working so I just mention some name in it and it is working but it is not taking database column. Don't know why! Please help
Thank you in advance.
This is the method ITEM I am using to take collections. Way to write is
autocompleteMenu1.Items = Database column
My code:
[DefaultValue(null)]
public string[] Items
{
get
{
if (sourceItems == null)
return null;
var list = new List<string>();
foreach (AutocompleteItem item in sourceItems)
list.Add(item.ToString());
return list.ToArray();
}
set { SetAutocompleteItems(value);
}
Here is the assignment of String [] to Item method but I want to add database column instead of string [] ... how can I do this...?
this.autocompleteMenu1.Items = new string []
{
"Jamal",
"Javed",
"Jameel",
"James",
"Jamshed",
"abc",
"abcd",
"Ahmed",
};

Lucene search not working

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

Using Linq to aggregate from array to single var

I have an accordion that binds data for each item from an array.
I want that for every time that I bound the data I will loop through all of the array and aggregate all of the items with the same id and create a long string with a name from a cell. In the code the name oneJob.order_id does not exist and I don't know why.
protected string GetAllProffesions(int orderID)
{
IEnumerable<string> allProf;
orderID = 544;
Job[] curItems = null;
curItems = JobManager.GetJobs(RangeID, GetParam());
allProf = from oneJob in curItems
where oneJob.order_id == orderID
select oneJob.profession_name;
return Convert.ToString(allProf);
}
This is because your job class doesn't have a property called order_id. Check your spelling.
Also, you probably don't want to do Convert.ToString(allProf), as I expect this will give you the type name instead of all the professions concatenated. Try this instead:
string.Join(", ", allProf.ToArray());

Categories

Resources