I want to write a simple application that takes data from a database and formats it to a Json file. The catch is, that the views from which I'm getting the data are supposed to be changeable.
That means the Json can't be serialized from a rootclass. Also, I need to make sure if the tables have a parent/child connection this is depicted as well.
In the code below I have created a dataset to give you an idea of what I mean.
static void Main(string[] args)
{
DataSet dsSet = new DataSet("OrderManagement");
DataTable tCustumer = new DataTable("Custumer");
DataTable tOrder = new DataTable("Order");
tCustumer.Columns.Add("CustumerId");
tCustumer.Columns.Add("Name");
tOrder.Columns.Add("OrderId");
tOrder.Columns.Add("CustumerId");
tOrder.Columns.Add("Article");
tCustumer.Rows.Add("1", "Chris");
tCustumer.Rows.Add("2", "Ronja");
tCustumer.Rows.Add("3", "Thomas");
tOrder.Rows.Add("1", "1", "chocolate");
tOrder.Rows.Add("2", "1", "apples");
tOrder.Rows.Add("3", "2", "dogfood");
tOrder.Rows.Add("4", "3", "keyboard");
tOrder.Rows.Add("4", "3", "tomatos");
tOrder.Rows.Add("4", "3", "green tea");
dsSet.Tables.Add(tCustumer);
dsSet.Tables.Add(tOrder);
dsSet.Relations.Add(
"RelationCustumerOrder",
dsSet.Tables["Custumer"].Columns["CustumerId"],
dsSet.Tables["Order"].Columns["CustumerId"], false
);
dsSet.AcceptChanges();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.All;
string text = JsonConvert.SerializeObject(dsSet, Formatting.Indented, settings);
}
This is the Json I want it to output:
{"Custumer": [
{
"CustumerId": "1",
"Name": "Chris"
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
},
]
},
{
"CustumerId": "2",
"Name": "Ronja"
"Order": [
{
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
}
]
},
{
"CustumerId": "3",
"Name": "Thomas"
"Order": [
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}
]
}],}
This is what I do get:
{"Custumer": [
{
"CustumerId": "1",
"Name": "Chris"
},
{
"CustumerId": "2",
"Name": "Ronja"
},
{
"CustumerId": "3",
"Name": "Thomas"
}],
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
},
{
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}]}
You can do this in couple of steps.
Step 1 : Set Relation.Nested Property as True.
dsSet.Relations.Add(
"RelationCustumerOrder",
dsSet.Tables["Custumer"].Columns["CustumerId"],
dsSet.Tables["Order"].Columns["CustumerId"]
);
dsSet.Relations[0].Nested = true;
Step 2 : Convert to Xml.
StringWriter sw = new StringWriter();
dsSet.WriteXml(sw);
string xmlString = sw.ToString();
Step 3: Serialize as Json for final result
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.All;
string jsonResult = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
Final Output for the sample would be
{
"OrderManagement": {
"Custumer": [
{
"CustumerId": "1",
"Name": "Chris",
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
}
]
},
{
"CustumerId": "2",
"Name": "Ronja",
"Order": {
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
}
},
{
"CustumerId": "3",
"Name": "Thomas",
"Order": [
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}
]
}
]
}
}
Related
I am sending request data like this
{
"1": "a",
"2": "b",
"3": "c",
"4": "d",
"5": "e",
"array": [
{
"GroupID": "NUMBER",
"CodeID": "ONE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "TWO",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "THREE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "FOUR",
"Value": "1"
}
]
}
Response data is received through the API like this
{
"Code": "00",
"Msg": "SUCCESS",
"Data": [
{
"a": "1",
"b": "2",
"c": "3",
"d": "4",
"e": "5",
"f": "6",
"g": "7",
"h": "8",
"array": [
{
"GroupID": "NUMBER",
"CodeID": "ONE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "TWO",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "THREE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "FOUR",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "FIVE",
"Value": "0"
},
{
"GroupID": "NUMBER",
"CodeID": "SIX",
"Value": "0"
}
]
},
{
"a": "9",
"b": "10",
"c": "11",
"d": "12",
"e": "13",
"f": "14",
"g": "15",
"h": "16",
"agreements": [
{
"GroupID": "NUMBER",
"CodeID": "ONE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "TWO",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "THREE",
"Value": "1"
},
{
"GroupID": "NUMBER",
"CodeID": "FOUR",
"Value": "0"
},
{
"GroupID": "NUMBER",
"CodeID": "FIVE",
"Value": "0"
},
{
"GroupID": "NUMBER",
"CodeID": "SIX",
"Value": "0"
}
]
}
]
}
I wrote a code like this that compares data and data and selects only the data that matches the requested data.
I put all the response data in the list and wrote the code like this
List<user_model> list= new List<user_model>();
List<user_model> list2= new List<user_model>();
foreach (user_model um in list)
{
if (um.array[0].Value == param["7"].ToString() &&
um.array[1].Value == param["8"].ToString() &&
um.array[2].Value == param["9"].ToString() &&
um.array[3].Value == param["10"].ToString())
{
list2.Add(bm);
}
}
Is there a way to code my code more concisely through lambda expressions?
Assuming bm is a typo you could do something like
list2.AddRange(
list.Where( um =>
um.array[0].Value == param["7"].ToString() &&
um.array[1].Value == param["8"].ToString() &&
um.array[2].Value == param["9"].ToString() &&
um.array[3].Value == param["10"].ToString()
)
);
If your values are arrays and not strings then you need to do an array compare, how you do this is up to you, e.g.
um.array[0].Except(param["7"]).Count() > 0
um.array[0].SequenceEquals( param["7"] )
there may be a point where it makes sense to pull this comparision logic out into a separate comparer class. There will be existing answers detailing that
I have this Model that hold list months Jan - Dec. I want user to be set start day of the logs example 26 Dec to Jan 25 or Jan 1 - Jan 31
public class SalaryMonth
{
public int Id { get; set; }
public int StartMonth { get; set; }
public int StartDay { get; set; }
public int EndMonth { get; set; }
public int EndDay { get; set; }
public string Name { get; set; }
}
How do I get the SalaryMonth based on the date supplied and but be one month this my business logic which always return null
namespace Contracts.Attendances
{
public interface IAttendanceService
{
Task<SalaryMonth> GetASalaryMonthByDate(DateTime date);
}
public class AttendanceService : IAttendanceService
{
/.../
public async Task<SalaryMonth> GetASalaryMonthByDate(DateTime date) {
var day = date.Day;
var month = date.Month;
var result = await _context.SalaryMonths.
.FirstOrDefaultAsync(p => (p.StartMonth == month && p.StartDay >= day && p.StartDay <= day)
|| ( p.EndMonth == month && p.EndDay >= day && p.EndDay <= day));
return result;
}
}
}
Json from Database
{
"SalaryMonth": [
{
"Id": "3",
"StartMonth": "2",
"StartDay": "26",
"EndMonth": "3",
"EndDay": "25",
"Name": "March"
},
{
"Id": "4",
"StartMonth": "3",
"StartDay": "26",
"EndMonth": "4",
"EndDay": "25",
"Name": "April"
},
{
"Id": "5",
"StartMonth": "4",
"StartDay": "26",
"EndMonth": "5",
"EndDay": "25",
"Name": "May"
},
{
"Id": "6",
"StartMonth": "5",
"StartDay": "26",
"EndMonth": "6",
"EndDay": "25",
"Name": "June"
},
{
"Id": "7",
"StartMonth": "6",
"StartDay": "26",
"EndMonth": "7",
"EndDay": "25",
"Name": "July"
},
{
"Id": "8",
"StartMonth": "7",
"StartDay": "26",
"EndMonth": "8",
"EndDay": "25",
"Name": "August"
},
{
"Id": "9",
"StartMonth": "8",
"StartDay": "26",
"EndMonth": "9",
"EndDay": "25",
"Name": "September"
},
{
"Id": "10",
"StartMonth": "9",
"StartDay": "26",
"EndMonth": "10",
"EndDay": "25",
"Name": "October"
},
{
"Id": "11",
"StartMonth": "10",
"StartDay": "26",
"EndMonth": "11",
"EndDay": "25",
"Name": "November"
},
{
"Id": "12",
"StartMonth": "11",
"StartDay": "26",
"EndMonth": "12",
"EndDay": "25",
"Name": "December"
},
{
"Id": "2",
"StartMonth": "2",
"StartDay": "26",
"EndMonth": "2",
"EndDay": "25",
"Name": "February"
},
{
"Id": "1",
"StartMonth": "12",
"StartDay": "26",
"EndMonth": "1",
"EndDay": "25",
"Name": "January"
}
]
}
How to I query the record to allow for users to get Salary month from supplied date. Example user provides any date between 26/12/2019 to 26/01/2020 the result must January since that date is in Jan Month because Jan StartMonth is 12 and StartDate 26 and EndMonth is 1 and EndDate 25
So I think I know what you’re trying to do. And if I understand correctly then your logic is a little mixed up in your linq call.
Given any day, that day cannot be less than or equal to a date and greater than or equal to that same date unless it is the same date.
So you need to do:
C# Code:
.FirstOrDefaultAsync(p => (p.StartMonth == month && p.StartDay <= day) || ( p.EndMonth == month && p.EndDay >= day ));
Hope this helps.
I have two arrays variables and values like below
arraydata1 =
[
{
"id": "1",
"name": "aaa"
},
{
"id": "2",
"name": "bbb"
},
{
"id": "3",
"name": "ccc"
},
{
"id": "4",
"name": "ddd"
},
{
"id": "12",
"name": "aaa"
}
]
and
arraydata2 =
[
{
"id": "111",
"tablename": "aaa"
},
{
"id": "222",
"tablename": "bbb"
}
]
I want to compare arraydata1.name == arraydata2.tablename and if matching then form new array from arraydata1 .
output is -
[
{
"id": "1",
"name": "aaa"
},
{
"id": "2",
"name": "bbb"
},
{
"id": "12",
"name": "aaa"
}
]
I have more than 2000+ records to compare in arraydata1 how to reduce time as well. I can use normal foreach but it will take too much time to compare.
I was doing inside logic app using 2 foreach so it is taking time. so i thought better to use c# code.
One Linq solution could look like this:
var tableNameKeys = arraydata2.Select(t => t.tablename).ToHashSet();
var resultArray = arraydata1.Where(x => tableNameKeys.Contains(x.name)).ToArray();
The advantage of this approach is that HashSet.Contains
... is an O(1) operation.
Result:
I run a query that returns me a list of customers orders:
SELECT cust_no, cust_name, order_no, order_name FROM CustomerOrders
In my Controller Action method, I do the following (_context is my DataContext):
var results = _context.CustomerOrders.ToList();
return Json(results, JsonRequestBehavior.AllowGet);
When I inspect this in the debugger, I see the list of objects, but not being too familiar with Json, I am not sure how this would look when it as a Json string. The format I want is:
{
"Customer": {
"cust_no": "123",
"cust_name": "john",
"Orders": [
{
"order_no": "1",
"order_name": "order1"
},
{
"order_no": "2",
"order_name": "order2"
}
]
},
"Customer": {
"cust_no": "456",
"cust_name": "jane",
"Orders": [
{
"order_no": "3",
"order_name": "order3"
},
{
"order_no": "4",
"order_name": "order4"
}
]
}
}
I currently can get into this:
{ Customer = "123", cust_name = "John", Orders = "1", oder_no = "order1" }
with:
_context.CustomerOrders.Select(x => new
{
Customer= x.cust_no, x.cust_name,
Orders = x.order_no, x.order_name});
public ActionResult GetCustomerOrders()
{
JsonResult result = null;
try
{
var results = new {Customers = _context.CustomerOrders.ToList()};
return Json(results,JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
//Log
}
return result;
}
You can't have JSON key-value pairs with the same key at the same level of nesting (in your case level 0). If you want, you can return an anonymous type by doing something like:
var results = new {Customers = _context.CustomerOrders.ToList()};
NOTE - Forgot to add that the above code will look like:
{
Customers: [{
"cust_no": "123",
"cust_name": "john",
"Orders": [{
"order_no": "1",
"order_name": "order1"
}, {
"order_no": "2",
"order_name": "order2"
}]
}, {
"cust_no": "456",
"cust_name": "jane",
"Orders": [{
"order_no": "3",
"order_name": "order3"
}, {
"order_no": "4",
"order_name": "order4"
}]
}]
}
Check the specification for JSON here: http://www.json.org/
EDIT - (in response to fixing your Linq Query)
The following is what you need:
var results = (from co in _context.CustomerOrders
group co by new { co.cust_no, co.cust_name } into orders
select new
{
Customer = new
{
cust_name = orders.Key.cust_name,
cust_no = orders.Key.cust_no,
Orders = orders.Select(o=> new{o.order_name,o.order_no })
}
}).AsEnumerable();
return Json(results, JsonRequestBehavior.AllowGet);
The results using mock data should look like the following:
[{
"Customer": {
"cust_name": "ted",
"cust_no": "1441865486",
"Orders": [{
"order_name": "ted1271196444",
"order_no": "1877898370"
}, {
"order_name": "ted1137404580",
"order_no": "1033969821"
}, {
"order_name": "ted113580415",
"order_no": "844051358"
}, {
"order_name": "ted842422359",
"order_no": "1063097922"
}, {
"order_name": "ted2140579126",
"order_no": "1170215299"
}, {
"order_name": "ted843928549",
"order_no": "2143378901"
}]
}
}, {
"Customer": {
"cust_name": "Jack",
"cust_no": "1258770771",
"Orders": [{
"order_name": "Jack879867938",
"order_no": "585569719"
}, {
"order_name": "Jack1423388998",
"order_no": "209013154"
}]
}
}, {
"Customer": {
"cust_name": "joe",
"cust_no": "1223478754",
"Orders": [{
"order_name": "joe1283306017",
"order_no": "1305330220"
}, {
"order_name": "joe1369830458",
"order_no": "1996259538"
}, {
"order_name": "joe1772918032",
"order_no": "1265675292"
}, {
"order_name": "joe535974281",
"order_no": "837890619"
}, {
"order_name": "joe194556914",
"order_no": "812224857"
}, {
"order_name": "joe28812423",
"order_no": "515669909"
}, {
"order_name": "joe2004245093",
"order_no": "1634742463"
}]
}
}, {
"Customer": {
"cust_name": "jill",
"cust_no": "659748358",
"Orders": [{
"order_name": "jill1462582377",
"order_no": "1817173079"
}, {
"order_name": "jill1848627650",
"order_no": "830495643"
}, {
"order_name": "jill727215465",
"order_no": "728808273"
}, {
"order_name": "jill1071911623",
"order_no": "824043403"
}, {
"order_name": "jill126843849",
"order_no": "1654825240"
}]
}
}]
In my c# project I use Json.net Library.
I have long Json with many subfields, for ex:
{
"count": 10,
"Foo1": [
{
"id": "1",
"name": "Name1"
},
{
"id": "2",
"name": "Name3"
},
{
"id": "3",
"name": "Name4"
}
],
"Foo2": [
{
"id": "4",
"name": "Name3",
"specific_field": "specific_values1"
},
{
"id": "5",
"name": "Name3",
"specific_field": "specific_values2"
},
{
"id": "6",
"name": "Name3",
"specific_field": "specific_values3"
}
],
"Foo3": [
{
"id": "7"
},
{
"id": "8"
},
{
"id": "9"
}
]
}
And I need to get List of all specific_field (id 4-6), but cant deserialized json to object, because Foo1, Foo2 ... changed dynamically.
I want to know, is this possible to get values of specific_field when i have only json?
I think, I found solution:
var list = new List<string>();
var result = ((JToken)json);
foreach (var res in result)
{
list.AddRange(from foo in res.First let ret = foo["specific_field"] where (dynamic) ret != null select foo["specific_field"].ToString());
}
In comment, provide, what do you think about it?
You could use dynamics:
string json = "your JSON string comes here";
dynamic deserializedValue = JsonConvert.DeserializeObject(json);
var values = deserializedValue["Foo2"];
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine(values[i]["specific_field"]);
}