Search a Json object array- List vs Dictionary - c#

I deserialized a JsonResponse using the below code.
var data = (JObject)JsonConvert.DeserializeObject(jsonResponse);
I got the response string which looks something like this
{
"results":[
{
"url":"tickets/2063.json",
"id":20794,
"subject":"Device not working",
"created_date": "2018-01-10T13:03:23Z",
"custom-fields":[
{
"id":25181002,
"value":34534
},
{
"id":2518164,
"value":252344
}
]
}
]
}
My objective is to read certain fields in this array of json objects and insert into a database. The fields i require are id, subject, created_date, member_id.
The member id is part of the custom fields. member_id is the value where id=2518164. I've used List to store this, can you let me know if List or Dictionary is better for this case. How to implement a dictionary
var data = (JObject)JsonConvert.DeserializeObject(jsonResponse);
var tickets = data["results"].ToList();
foreach (var ticketItem in tickets){
Int64? ticketFormId = ticketItem["id"].Value<Int64>();
string subject = ticketItem["subject"].Value<string>();
DateTime createdDate = ticketItem["created_date"].Value<DateTime>();
//Do you think for the next step a dictionary is better or a List is better, since I want to search for a particular id=2518164
var fieldsList = ticketItem["fields"].ToList();
foreach(var fieldItem in fieldList){
Int64? fieldId = fieldItem["id"].Value<Int64>();
if(fieldId!=null && fieldId == 2518164){
memberId = fieldItem["value"].Value<string>();
}
}
}

If you're next step to insert them all into the database, just store them into a list. A dictionary is only useful to search the item by a key.
You can also use linq to process the json in a simpler way:
var tickets = JObject.Parse(jsonResponse)["results"]
.Select(ticket => new
{
Id = (long)ticket["id"],
Subject = (string)ticket["subject"],
CreatedDate = (DateTime)ticket["created_date"],
MemberId = (long)ticket["custom-fields"]
.FirstOrDefault(cf => (int)cf["id"] == 2518164)
?["value"],
})
.ToList();

Related

MongoDB/ - Update Multiple Fields inside an array, keep their original value, but update datatype

So the problem I have is that I want to be able to filter on a particular criteria.
I originally tried to filter based on the datatype of the field, I am struggling to do this with arrays though. This did work at one point with single fields, but now not having much joy.
Then as part of the update I want to set specific fields inside the array from string datatype to say integer.
So to summarise I want to do the following:
Filter where the fields in the array are string datatype as I want to update them.
Update only the datatype and retain the value(essentially converting from string to integer)
Get results with modified count to ensure it was successful.
Thanks in advance.
var mongoDb = mongoClient.GetDatabase(config.DatabaseName); // , new MongoDatabaseSettings() { WriteConcern = WriteConcern.Unacknowledged }
var objectId = new ObjectId("63d38c71ef08fde3fbf1b9da");
var filter = Builders<BsonDocument>.Filter.Eq("_id", objectId);
var updateQuery = new BsonDocument { { "$set", new BsonDocument { { "CheckFinalization.Check.ItemDetail.$[].ItemNumber", new BsonDocument { { "$toInt", "$CheckFinalization.Check.ItemDetail.$[].ItemNumber" } } } } } };
var updatePipeline = Builders<BsonDocument>.Update.Pipeline(PipelineDefinition<BsonDocument, BsonDocument>.Create(updateQuery));
var dataCollection = mongoDb.GetCollection<BsonDocument>(config.CollectionName);
var recordResult = dataCollection.Find(filter).Limit(100).ToList();
// check we have records to update.
if (recordResult.Any())
{
var result = dataCollection.UpdateMany(filter, updatePipeline);
if (result.ModifiedCount > 0)
{
// Success
}
else
{
// Failed
}
}`

How do i extract from a nested dictionary?

I have created a nested dictionary with the following:
Dictionary<DateTime, Dictionary<string, string>> dateDict =
new Dictionary<DateTime, Dictionary<string, string>>();
I then enter values to this dictionary using the following:
while (reader.Read())
{
DateTime date = DateTime.Parse(reader["Event_Date"].ToString());
string name = reader["Event_Name"].ToString();
string guid = reader["Event_GUID"].ToString();
dateDict.Add(date, new Dictionary<string, string>());
dateDict[date].Add(name, guid);
}
My question is how do I correctly pull the variables back out from the nested dictionary?
I have this loop running to pull values out and assign them to DateTimePickers and TextFields:
for (int i = 0; i < dateDict.Count; i++)
{
DateTime keyVar = dateDict.ElementAt(i).Key;
eventDateBoxes[i].Value = keyVar;
eventTextBoxes[i].Text = dateDict[keyVar[]];
}
The eventTextBoxes part is where im getting stuck on how to pull the value from the nested dictionary, hence why that part of the code is wrong/incomplete.
I can't use tuples as I am using .NET lower than 4 and can't seem to wrap my head around making a custom class to act as its own tuple or multidictionary.
It sounds like you don't need a Dictionary<DateTime, Dictionary<string, string>> since you have only one item inside your inner dictionary, you need a Dictionary<DateTime, Dictionary<string, Event>> where Event is a class that holds you event data. Something like:
public class Event
{
public string Name {get; set;}
public string Guid {get; set;} // you could actually use the GUID type here!
}
Then you'd populate it like:
while (reader.Read())
{
DateTime date = DateTime.Parse(reader["Event_Date"].ToString());
string name = reader["Event_Name"].ToString();
string guid = reader["Event_GUID"].ToString();
dateDict.Add(date, new Event() { Name = name, Guid = guid };
}
Then when you get an item from your dictionary by key:
var item = dateDict[someKey];
You can get your name and guid back:
var name = item.Name;
var guid = item.guid;
Additionally, since you are iterating through your dictionary by numerical index rather than by key, it seems likely that you probably don't need a dictionary at all. Maybe all you need to do is add a Date property to your Event and just have an List<Event>.
I would use a foreach or a LINQ query. But it's not clear what you want as DateTimePicker.Text:
List<DateTimePicker> eventDateBoxes = dateDict
.Select(kv => new{
Date = kv.Key,
EventName = kv.Value["Event_Name"],
EventGuid = kv.Value["Event_GUID"],
})
.Select(x => new DateTimePicker{ Value = x.Date, Text = x.EventName })
.ToList();
This is the basic outline of what you would do:
foreach (var element in dateDict)
{
eventDateBoxes[i].Value = element.Key;
foreach (var subElement in element.Value)
{
eventTextBoxes[i].Text = subElement.Value;
}
}
As others point out in the comment, there can be no one-to-one relationship between the elements in the outer dictionary and the text boxes as there can (potentially) be multiple entries in the sub-element.

C# - Nested Array/Data structures

Recently, I have been getting into C# (ASP.NET) and moving on from PHP. I want to achieve something like this:
mainArray (
array 1 (
'name' => 'example'
),
array 2 (
'name' => 'example2'
)
);
I know that you can use an Array in C# however, you must indicate the length of the Array before doing so which is where the problem is.
I want to loop through a Database in a Class function which returns an Array of all the columns, ie:
id, username, email.
I have tried:
public Array search_bustype(string match, string forthat)
{
db = new rkdb_07022016Entities2();
var tbl = (from c in db.tblbus_business select c).ToArray();
List<string> List = new List<string>();
int i = 0;
foreach (var toCheck in tbl)
{
if (toCheck.BusType.ToString() == match)
{
if (forthat == "Name")
{
List.Add(toCheck.Name);
}
if (forthat == "Address")
{
}
}
i++;
}
return List.ToArray();
}
But as you can see, I am having to only return the single column because the List is not multidimensional (can't be nested).
What can I use to solve this issue? I have looked at some links:
C# Arrays
StackOverflow post
But these again are an issue for my structure since I don't know how many index's I need in the Array when declaring it - The Database grows everyday.
Thanks in advance.
Try something like this. First, define a class for your business model.
public class Person
{
public string Name {get;set;}
public string Address {get;set;}
}
Then use a generic list instead of a string list.
public Person[] search_bustype(string match, string forthat)
{
var db = new rkdb_07022016Entities2();
List<Person> personList = new List<Person>();
foreach (var toCheck in db.tblbus_business.Where(b => b.BusType.ToString() == match))
{
var model = new Person { Name = toCheck.Name, Address = toCheck.Address };
personList.Add(model);
}
return personList.ToArray();
}
I'm not sure what you are trying to do with the forthat variable.
You can use a list of lists
IList<IList<string>> multiList;

Get display name for logical name

I have list of logical names for an entity for which I need to retreive the displayname.
For eg I have
List<string> _list=new List<string>();
_list.Add("address_City")
_list.Add("first_name")
The display names for them are Address City and First Name
RetrieveEntityRequest req = new RetrieveEntityRequest();
req.RetrieveAsIfPublished = true;
req.LogicalName = "account";
req.EntityFilters = EntityFilters.Attributes;
RetrieveEntityResponse resp = (RetrieveEntityResponse)_orgService.Execute(req);
for (int iCnt = 0; iCnt < resp.EntityMetadata.Attributes.ToList().Count; iCnt++)
{
if(resp.EntityMetadata.Attributes.ToList()[iCnt].DisplayName.LocalizedLabels.Count>0)
{
string displayName = resp.EntityMetadata.Attributes.ToList()[iCnt].DisplayName.LocalizedLabels[0].Label;
string logicalName = resp.EntityMetadata.Attributes.ToList()[iCnt].LogicalName;
}
}
This code retrieves all the record .Is there a way to create some custom query where I can just pass this List<string> and retrieve there display names?
Linq would work great. Just taking your list of logical names and returning a list of display names would look like this:
List<string> _list = new List<string>()
{
"address_City",
"first_name"
};
List<string> _displayList = new List<string>();
if (entityMetaData.Attributes.Any())
{
_displayList.AddRange(from lName in _list
select (entityMetaData.Attributes.FirstOrDefault(n => n.LogicalName.Equals(lName)))
into attribute
where attribute.DisplayName.UserLocalizedLabel != null
select attribute.DisplayName.UserLocalizedLabel.Label);
}
You could use the same logic when returning a dictionary with the logicalName and displayName. Your response from the entity request already has all the metadata, so you don't lose much time at all sifting through that data and getting what you want.

Store each parsed value of JSON into an array

I'm working on the Array in C#, as following code below, the uricontent is a List in which each string contains one JSON value, I could parse the content, however, I want to have one other array or List to store each parsed value, in the example below, rooms variable can store each time one JSON parsed value, now I wish to store those parsed values in one array.
int i = 0;
while (uricontent.Count != 0)
{
var rooms = JObject.Parse(uricontent[i].ToString())
["rooms"]
.Select(x => new
{
roomID = (string)x["room_name"],
Name = WebUtility.HtmlDecode((string)x["room_name"]),
Price = PriceHelper.Convert((string)x["discountedTotal"]),
Currency = (string)x["currency"],
Occupan = (int)x["adult"]
}).ToArray();
i++;
}
rooms {<>f_AnonymousType11[1]<>f_AnonymousType11[]
[0] { roomID = "Superior 1st floor", Name = "Superior 1st floor", Price = 207.4, Currency = "EUR", Occupan = 2 }
As indicating above, the rooms overwrite the data in each iteration, how can I store those values in one other array like
[1].....
[2].....
....
Thanks
I think what you need is the SelectMany method. SelectMany concatenates all of the IEnumerables generated by the inner Select statements, and returns them as a single IEnumerable, which can then be converted into an array:
var rooms = uricontent
.SelectMany(
uriContentElementJson =>
{
JObject uriContentElement = JObject.Parse(uriContentElementJson);
return uriContentElement["rooms"].Select(
room => new
{
RoomID = (string)room["room_name"],
Name = WebUtility.HtmlDecode((string)room["room_name"]),
Price = PriceHelper.Convert((string)room["discountedTotal"]),
Currency = (string)room["currency"],
Occupant = (int)room["adult"]
});
})
.ToArray();

Categories