accessing json property with given values - c#

var orderJson = JsonConvert.DeserializeObject<dynamic>(httpResultStr);
var orderidCount = orderJson.data.orderUuids.Count;
for (int i = 0; i <= orderidCount; i++)
{
var orderId = orderJson.data.orderUuids[i]; // my fail attempt. Didnt work
var map = orderJson.data.ordersMap;
foreach (var d in map)
{
var receipt = d.fareInfo.totalPrice;
Console.WriteLine(receipt);
}
}
Im trying to access the ordersMap members with the given values in orderUuids object. Inside the ordersMap Ids contain the fareInfo.totalPrice property that I'm trying to access. How would I go about achieving this?
[![json tree with ordersMap. Trying to access its members with the given values in orderUuids object.][1]][1]

You can make a partial/full map using the JSON file and use JsonConvert.DeserializeObject<>(json).
Other solution could be create a partial map using an anonymous type. Here is a code snip.
var anonymousTypeObject = new
{
status = "",
data = new
{
ordersMap = new Dictionary<string, JToken>(),
orderUuids = new string[0]
}
};
var obj = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
foreach (var kvp in obj.data.ordersMap)
{
var totalPrice = kvp.Value["fareInfo"]?["totalPrice"]?.ToString();
Debug.WriteLine($"{kvp.Key} -> {totalPrice}");
}
EDIT If you don't want any map use this solution.
var jObj = JsonConvert.DeserializeObject<JObject>(json);
var orderUuids = jObj.SelectToken("data.orderUuids")?.Values<string>();
foreach (var orderUuid in orderUuids)
{
var totalPrice = jObj.SelectToken($"data.ordersMap.{orderUuid}.fareInfo.totalPrice")?.Value<double>();
Debug.WriteLine($"{orderUuid} -> {totalPrice}");
}

Related

Update list item multiple lookup value field Microsoft Graph

I am trying to update a multiple lookup value field for a list item.
I tried the following code :
List < QueryOption > options = new List < QueryOption > {
new QueryOption("$expand", "listitem")
};
//get drive item with list item
var driveItem = graphClient.Sites[IdGestDoc].Drive.Items[itemResult.Id].Request(options).GetAsync().Result;
var fieldValueSet = new FieldValueSet {
AdditionalData = new Dictionary < string,
object > {
{
"Theme_fonctionnel#odata.type",
"Collection(Edm.String)"
}, {
"Theme_fonctionnel", ThemeFonctionnel.ToArray()
} //ThemeFonctionnel is a List<string> => lookupid
}
};
await graphClient.Sites[IdGestDoc].Lists["Documents"].Items[driveItem.ListItem.Id].Fields.Request().UpdateAsync(fieldValueSet);
But this code don't work and I don't find what I am missing.
Any help will be appreciated !
To set a Lookup field, you need to set the property by passing in the property name and the addition 'LookupId':
string propertyName = "Theme_fonctionnel";
var fieldValueSet = new FieldValueSet();
var propertyValuesArray = options.ToArray();
var attributes = new Dictionary<string, object>();
//first, we need to specify the input data type
string oDataTypeInfoPropertyName = propertyName + "LookupId#odata.type";
string oDataDataType = "Collection(Edm.String)";
attributes.Add(oDataTypeInfoPropertyName, oDataDataType);
//next, we need to pass the values as an array
string newPropertyName = propertyName + "LookupId";
attributes.Add(newPropertyName, propertyValuesArray);
fieldValueSet.AdditionalData = attributes;

How to add distinct value in database using Entity Framework

IEnumerable<WebsiteWebPage> data = GetWebPages();
foreach (var value in data)
{
if (value.WebPage.Contains(".htm"))
{
WebsiteWebPage pagesinfo = new WebsiteWebPage();
pagesinfo.WebPage = value.WebPage;
pagesinfo.WebsiteId = websiteid;
db.WebsiteWebPages.Add(pagesinfo);
}
}
db.SaveChanges();
I want to add only distinct values to database in above code. Kindly help me how to do it as I am not able to find any solution.
IEnumerable<WebsiteWebPage> data = GetWebPages();
foreach (var value in data)
{
if (value.WebPage.Contains(".htm"))
{
var a = db.WebsiteWebPages.Where(i => i.WebPage == value.WebPage.ToString()).ToList();
if (a.Count == 0)
{
WebsiteWebPage pagesinfo = new WebsiteWebPage();
pagesinfo.WebPage = value.WebPage;
pagesinfo.WebsiteId = websiteid;
db.WebsiteWebPages.Add(pagesinfo);
db.SaveChanges();
}
}
}
This is the code that I used to add distinct data.I hope it helps
In addition to the code sample Furkan Öztürk supplied, Make sure your DB has a constraint so that you cannot enter duplicate values in the column. Belt and braces approach.
I assume that by "distinct values" you mean "distinct value.WebPage values":
// get existing values (if you ever need this)
var existingWebPages = db.WebsiteWebPages.Select(v => v.WebPage);
// get your pages
var webPages = GetWebPages().Where(v => v.WebPage.Contains(".htm"));
// get distinct WebPage values except existing ones
var distinctWebPages = webPages.Select(v => v.WebPage).Distinct().Except(existingWebPages);
// create WebsiteWebPage objects
var websiteWebPages = distinctWebPages.Select(v =>
new WebsiteWebPage { WebPage = v, WebsiteId = websiteid});
// save all at once
db.WebsiteWebPages.AddRange(websiteWebPages);
db.SaveChanges();
Assuming that you need them to be unique by WebPage and WebSiteId
IEnumerable<WebsiteWebPage> data = GetWebPages();
foreach (var value in data)
{
if (value.WebPage.Contains(".htm"))
{
WebsiteWebPage pagesinfo = new WebsiteWebPage();
if (db.WebsiteWebPages.All(c=>c.WebPage != value.WebPage|| c.WebsiteId != websiteid))
{
pagesinfo.WebPage = value.WebPage;
pagesinfo.WebsiteId = websiteid;
db.WebsiteWebPages.Add(pagesinfo);
}
}
}
db.SaveChanges();
UPDATE
To optimize this (given that your table contains much more data than your current list), override your equals in WebsiteWebPage class to define your uniqueness criteria then:
var myWebsiteWebPages = data.select(x=> new WebsiteWebPage { WebPage = x.WebPage, WebsiteId = websiteid}).Distinct();
var duplicates = db.WebsiteWebPages.Where(x=> myWebsiteWebPage.Contains(x));
db.WebsiteWebPages.AddRange(myWebsiteWebPages.Where(x=> !duplicates.Contains(x)));
this is a one database query to retrieve ONLY duplicates and then removing them from the list
You can use the following code,
IEnumerable<WebsiteWebPage> data = GetWebPages();
var templist = new List<WebsiteWebPage>();
foreach (var value in data)
{
if (value.WebPage.Contains(".htm"))
{
WebsiteWebPage pagesinfo = new WebsiteWebPage();
pagesinfo.WebPage = value.WebPage;
pagesinfo.WebsiteId = websiteid;
templist.Add(pagesinfo);
}
}
var distinctList = templist.GroupBy(x => x.WebsiteId).Select(group => group.First()).ToList();
db.WebsiteWebPages.AddRange(distinctList);
db.SaveChanges();
Or you can use MoreLINQ here to filter distinct the list by parameter like,
var res = tempList.Distinct(x=>x.WebsiteId).ToList();
db.WebsiteWebPages.AddRange(res);
db.SaveChanges();

How can I extract a string out of an object that contains this string?

I created a Yaml that looks like this:
Directories:
- ./Libraries:
- DLLList.yml
- ./Output:
- None
Now I deserialized that yaml into a list of Objects:
List<object> allDirectoriesList = new List<object>();
List<string> allFileNames = new List<string>();
using (var reader = new StringReader(File.ReadAllText("./FileConfig.yml")))
{
allDirectoriesList = deserializer.Deserialize<dynamic>(reader)["Directories"] as List<Object>;
}
foreach (var directory in allDirectoriesList)
{
var directoryAsDictionary = (Dictionary<object, object>)directory;
List<object> list = directoryAsDictionary.Select(kvp => kvp.Value).ToList();
IEnumerable<string> _fileList = list.Select(i => i.ToString());
List<string> fileList = _fileList.ToList<string>();
for (int i = 0; i < fileList.Count(); i++)
{
var x = (string)list[i];
}
}
directory is an object of type Dictionary where I converted it into a List in this part:
var directoryAsDictionary = (Dictionary<object, object>)directory;
List<object> list = directoryAsDictionary.Select(kvp => kvp.Value).ToList();
This list contains 1 object of type string, where the filename is stored. But I can't get these strings out of the objects. If I cast them, or convert them ToString(), I always get "System.Collections.Generic.List`1[System.Object]", but it has to be "DLLList.yml" in this case
Assuming you are using YamlDotNet:
List<object> allDirectoriesList = new List<object>();
using (var reader = new StringReader(File.ReadAllText("./FileConfig.yml")))
{
allDirectoriesList = new DeserializerBuilder().Build().Deserialize<dynamic>(reader)["Directories"] as List<object>;
}
foreach (var directory in allDirectoriesList)
{
var directoryAsDictionary = (Dictionary<object, object>)directory;
List<object> list = directoryAsDictionary.SelectMany(kvp => (List<object>)kvp.Value).ToList();
List<string> _fileList = list.Select(Convert.ToString).ToList();
foreach(var file in _fileList)
Console.WriteLine($"Item: {file} found in {Convert.ToString(directoryAsDictionary.Keys.First())}");
}
Basically you were trying to turn the dictionary value to a string, but it was a List. By using SelectMany, it can flatten all the lists into one and use that. There were a few redundant casts, which I've also removed. For future reference, try to make your structures as simple as possible and deserialise them into structs/classes - you'll find this a lot easier that way.

Pass query result to method (Linq, Wpf)

I have method to save all values from table to txt file:
UserDataDBsDataContext dataContext = new UserDataDBsDataContext();
List<UserData> usersL = (from u in dataContext.UserDatas
select u).ToList();
var properties = typeof(UserData).GetProperties();
var userValues = new List<string>();
foreach (var user in usersL)
{
var values = new List<object>();
foreach (var property in properties)
{
object value = property.GetValue(user, null);
values.Add(value);
}
userValues.Add(string.Join(",", values));
}
File.WriteAllLines("my_data.txt", userValues);
Now I have two query and I want to do exactly the same, so I tried to create separate method responsible for looping table values.
Loop Method:
public void loopProp(PropertyInfo[] properites, List<string> addedValues)
{
foreach (var qrl in ...........)
{
var values = new List<object>();
foreach (var property in properites)
{
object value = property.GetValue(qrl, null);
values.Add(value);
}
addedValues.Add(string.Join(",", values));
}
File.WriteAllLines("my_passed_data.txt", addedValues);
}
But I don't know, how to pass query result(ar or ud):
My code:
List<AutoRef> ar = (from a in rjdc.AutoRefs
select a).ToList();
List<UserDataRef> ud = (from u in rjdc.UserDataRefs
select u).ToList();
var propertiesAutoRef = typeof(AutoRef).GetProperties();
var autoValues = new List<string>();
var propertiesUserRef = typeof(UserDataRef).GetProperties();
var userValues = new List<string>();
//loopProp(propertiesAutoRef, autoValues);
//loopProp(propertiesUserRef, userValues);
Answering your concrete question. You should make the method generic and pass the source as IEnumerable<T>:
public void loopProp<T>(IEnumerable<T> source, PropertyInfo[] properites, List<string> addedValues)
{
foreach (var qrl in source)
{
// ...
}
File.WriteAllLines("my_passed_data.txt", addedValues);
}
Usage:
loopProp(ar, propertiesAutoRef, autoValues);
loopProp(ud, propertiesUserRef, userValues);
Probably you should pass the file path argument as well instead of hardcoding it inside the method.

Trouble Fetching Value in Variable

Basically here's my code which I'm having trouble with. Insanely new to mongoDB and would love to understand how to get values out of a JSON string that is returns in the variable 'line'.
public string get_data()
{
var client = new MongoClient();
var db = client.GetDatabase("test");
var collection = db.GetCollection<BsonDocument>("metacorp");
var cursor = collection.Find("{'movie_name' : 'Hemin'}").ToCursor();
var line = "";
foreach (var document in cursor.ToEnumerable())
{
using (var stringWriter = new StringWriter())
using (var jsonWriter = new JsonWriter(stringWriter))
{
var context = BsonSerializationContext.CreateRoot(jsonWriter);
collection.DocumentSerializer.Serialize(context, document);
line = stringWriter.ToString();
}
}
var js = new JavaScriptSerializer();
var d = js.Deserialize<dynamic>(line);
var a = d["movie_name"];
return line;
}
This is the output I get if I return line:
{ "_id" : ObjectId("58746dcafead398e4d7233f5"), "movie_name" : "Hemin"
}
I want to be able to fetch the value 'Hemin' into 'a'.
I know this is not what you're asking for but since you're using the c# driver then I would recommend the following. Assumes you have a c# class corresponding to metacorp collection or at least a serializer that handles it. Hope it helps.
var client = new MongoClient();
var db = client.GetDatabase("test");
var collection = db.GetCollection<MetaCorp>("metacorp");
var m = collection.SingleOrDefault(x => x.Movie_Name == "Hemin"); // Assuming 0 or 1 with that name. Use Where otherwise
var movieName = "Not found";
if(m!= null)
movieName = m.Movie_Name;
You could have your dto class for movie ans just fetch the data from collection:
public class Movie
{
public ObjectId Id { get; set; }
public string movie_name { get; set;}
}
...
var client = new MongoClient();
var db = client.GetDatabase("test");
var collection = db.GetCollection<BsonDocument>("metacorp");
var movies = collection.Find(x=>x.movie_name == "Hemin").ToEnumerable();

Categories