I have created a Linq statement to get a list of items from the database. So I need to loop trough the query and append to object to then serialize to then be able to use as json in javascript. The problem is I cannot append to the declared object 'obj'. Can anyone help??
DataContext dataContext = new DataContext();
var query = from qr in dataContext.tblStocks
where qr.enable == true
select qr;
var obj = new JObject();
foreach (var item in query)
{
//obj = new JObject();
obj = ( new JObject(
new JProperty("stockID",item.stockID),
new JProperty("itemDepartmentID", item.itemDepartmentID),
new JProperty("item" , item.item),
new JProperty("description", item.description),
new JProperty("stockAmount", item.stockAmount),
new JProperty("priceExlVat", item.priceExlVat),
new JProperty("vat", item.vat),
new JProperty("priceIncVAT", item.priceIncVAT),
new JProperty("upc1", item.upc1),
new JProperty("upc2", item.upc2)
));
}
var serialized = JsonConvert.SerializeObject(obj);
return serialized;
You are reassigning obj each time through the loop hence all other data will be lost.
Easier to create an array:
obj = new JArray();
foreach (var item in query) {
obj.Add(new JObject(
new JProperty(...),
...));
}
Why don't you just serialize your object?
List<dynamic> obj = new List<dynamic>();
foreach(var item in query) {
obj.Add(new
{
itemDepartmentID = item.itemDepartmentID,
description = item.description,
...
});
}
var serialized = JsonConvert.SerializeObject(obj);
Alternative you could use an anonymous type in the query and just serialize the entire query for the query returns an IEnumerable<T> and this is converted automatically to an jsonArray:
DataContext dataContext = new DataContext();
var query = dataContext.tblStocks
.Where(stockItem => stockItem.enable)
.Select(stockItem => new
{
stockItem.stockID,
stockItem.itemDepartmentID,
stockItem.item,
stockItem.description,
stockItem.stockAmount,
stockItem.priceExlVat,
stockItem.vat,
stockItem.priceIncVat,
stockItem.upc1,
stockItem.upc2
});
return JsonConvert.SerializeObject(query);
Related
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}");
}
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.
how to convert :
A List :
var list = new List<string>(){"str1","str2"}
to a anonymous object :
var anonymousObject = new {str1 = "str1",str2 = "str2"}
during runtime
You can use the ExpandoObject which will give you the feature of dynamic type.
var list = new List<string>() { "str1", "str2" };
ExpandoObject obj = new ExpandoObject();
var store = (IDictionary<string, object>)obj;
list.ForEach(x => store.Add(x, x));
dynamic lst = obj;
var val = lst.str1; // Test
You can also use extension method represented below (from here).
Because converting list to dynamic object by iterating on items manually can be painful when there is many situations like this in your application.
You can use this extension method like this:
dynamic list = new List<string>() { "str1", "str2" }
.ToDictionary(dd => dd, dd => (object)dd)
.ToExpando();
The extension method:
public static ExpandoObject ToExpando(this IDictionary<string, object> dictionary)
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)expando;
// go through the items in the dictionary and copy over the key value pairs)
foreach (var kvp in dictionary)
{
// if the value can also be turned into an ExpandoObject, then do it!
if (kvp.Value is IDictionary<string, object>)
{
var expandoValue = ((IDictionary<string, object>)kvp.Value).ToExpando();
expandoDic.Add(kvp.Key, expandoValue);
}
else if (kvp.Value is ICollection)
{
// iterate through the collection and convert any strin-object dictionaries
// along the way into expando objects
var itemList = new List<object>();
foreach (var item in (ICollection)kvp.Value)
{
if (item is IDictionary<string, object>)
{
var expandoItem = ((IDictionary<string, object>)item).ToExpando();
itemList.Add(expandoItem);
}
else
{
itemList.Add(item);
}
}
expandoDic.Add(kvp.Key, itemList);
}
else
{
expandoDic.Add(kvp);
}
}
return expando;
}
Hashtable mainhash = new Hashtable();
testdata td = new testdata() { value = "td" };
td.hash.Add("1", "tdvalue1");
td.hash.Add("2", "tdvalue2");
td.hash.Add("3", "tdvalue3");
td.hash.Add("4", "tdvalue4");
td.hash.Add("5", "tdvalue5");
testdata td1 = new testdata() { value = "td1" };
td1.hash.Add("1", "td1value1");
td1.hash.Add("2", "td1value2");
td1.hash.Add("3", "td1value3");
td1.hash.Add("4", "td1value4");
td1.hash.Add("5", "td1value5");
testdata td2 = new testdata() { value = "td2" };
td2.hash.Add("1", "td2value1");
td2.hash.Add("2", "td2value2");
td2.hash.Add("3", "td2value3");
td2.hash.Add("4", "td2value4");
td2.hash.Add("5", "td2value5");
testdata td3 = new testdata() { value = "td3" };
td3.hash.Add("1", "td3value1");
td3.hash.Add("2", "td3value2");
td3.hash.Add("3", "td3value3");
td3.hash.Add("4", "td3value4");
td3.hash.Add("5", "td3value5");
testdata td4 = new testdata() { value = "td4" };
td4.hash.Add("1", "td4value1");
td4.hash.Add("2", "td4value2");
td4.hash.Add("3", "td4value3");
td4.hash.Add("4", "td4value4");
td4.hash.Add("5", "td4value5");
mainhash.Add(1, td);
mainhash.Add(2, td1);
mainhash.Add(3, td2);
mainhash.Add(4, td3);
mainhash.Add(5, td4);
how to select all the keys using SelectMany by Linq into one list??
what i need to do in this??
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x=> x.Keys);
what is wrong in this??
It doesn't know the type to use from Hashtable.Keys.
Try:
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x => x.Keys.Cast<string>());
But better: use Dictionary<TKey,TValue> instead of Hashtable.
try below query -
var values = mainhash.Values.Cast<testdata>().SelectMany(x => x.hash.Keys.Cast<string>());
But, use dictionary instead of hashtable. It actually reduce the overhead of casting the objects.
hope above code helps you !!
How can I convert my List object to List<CustomObjects>
Currently am doing as
var db = new DataClasses1DataContext();
var list =
(from t in db.CTRL_DATA_ERROR_DETAILs
select new {t.DATA_ERROR_KEY, t.CTRL_DATA_ERROR_MASTER.CREATION_DATE})
.ToList();
var cus = new List<CustomObjects>();
foreach (var list1 in list)
{
var cs = new CustomObjects
{
MasterColumn = list1.DATA_ERROR_KEY.ToString(),
ChildColumn = list1.CREATION_DATE.ToString()
};
cus.Add(cs);
}
Is there other good way to do this.
You should be able to create the CustomObject list in the initial step like so:
var db = new DataClasses1DataContext();
var cus =
(from t in db.CTRL_DATA_ERROR_DETAILs
select new CustomObjects { MasterColumn = t.DATA_ERROR_KEY.ToString(),
ChildColumn = t.CTRL_DATA_ERROR_MASTER.CREATION_DATE.ToString()})
.ToList();
I haven't compiled the code, but the concept should be right.