Nest Json data from MySql queries in C# - c#

Im trying to make a nested json with data get from a MySQL DB
For the moment i got
//Obtener el root de info
public List<Root> GetRoot()
{
using (var conexion = ObtenerConexion())
{
conexion.Open();
var query = #"SELECT id AS Id, fullname AS NombreCurso, MID(fullname, INSTR(fullname, ""RLAB""), 20) AS codigoOferta
FROM mo_course
WHERE MID(fullname, INSTR(fullname, ""RLAB""), 20) != '';";
var resultado = conexion.Query<Root>(query);
foreach (var item in resultado)
{
Root root = new Root();
root.codigoOferta = item.codigoOferta;
root.listaAlumnos = new List<ListaAlumno>();
roots.Add(root);
conexion.Close();
}
return roots;
}
}
public List<ListaAlumno> GetAlumnos(string codigoOferta)
{
using (var conexion = ObtenerConexion())
{
conexion.Open();
var query = #"SELECT mo_role_assignments.userid AS Id, firstname AS Nombre, lastname AS Apellido, LEFT(mo_user.idnumber, LENGTH(mo_user.idnumber - 2)) AS rutAlumno,
RIGHT(mo_user.idnumber, 1) AS dvAlumno, email AS Correo, mo_course.fullname AS NombreCurso, mo_course.idnumber AS codigoOferta,
FROM_UNIXTIME(startdate) AS fechaInicio, FROM_UNIXTIME(enddate) AS fechaFin
FROM mo_course
INNER JOIN mo_context ON mo_context.instanceid = mo_course.id
INNER JOIN mo_role_assignments ON mo_context.id = mo_role_assignments.contextid
INNER JOIN mo_user ON (mo_role_assignments.userid = mo_user.id)";
var resultado = conexion.Query<ListaAlumno>(query);
foreach (var item in resultado)
{
ListaAlumno alumno = new ListaAlumno();
alumno.codigoOferta = item.codigoOferta;
alumno.rutAlumno = item.rutAlumno;
alumno.dvAlumno = item.dvAlumno;
alumno.tiempoConectividad = 0;
alumno.estado = 0;
alumno.porcentajeAvance = 0;
alumno.fechaInicio = item.fechaInicio;
alumno.fechaFin = item.fechaFin;
alumno.fechaEjecucion = "";
alumno.listaModulos = new List<ListaModulo>();
listaAlumnos.Add(alumno);
}
conexion.Close();
}
return listaAlumnos;
}
}
but i cant find a way to do the variable to nest the data, since i getting the data as direct query the parameter "codigoOferta" in GetAlumnos is not working
The idea its to do the following
{
"rutOtec": "9999999-9",
"idSistema": 1350,
"token": "AAAAAA-ASSS-DDDDd-8FFF-2FFFFFFFFD2",
"codigoOferta": "RSJ-D444-555-666666",
"codigoGrupo": "RSJ-D444-555-666666",
"codigoEnvio": "RSJ-D444-555-666666",
"listaAlumnos": [
{
"rutAlumno": 255544466,
"dvAlumno": "4",
"tiempoConectividad": 199112,
"estado": 1,
"porcentajeAvance": 99,
"fechaInicio": "2022-07-28",
"fechaFin": "2022-10-24",
"fechaEjecucion": "2022-10-24",
"listaModulos": [
{
"codigoModulo": "ARS027773588877",
"tiempoConectividad": 7964,
"estado": 1,
"porcentajeAvance": 100,
"fechaInicio": "2022-07-28",
"fechaFin": "2022-10-24",
"listaActividades": [
{
"codigoActividad": "Excel"
},
{
"codigoActividad": "Video interactivo de introducci\u00f3n a Excel"
},
but since for each student in listaAlumno the data change i need to nest the variables

Related

Mapping nested List Property of items in MySQL query to objects

I want to get the details of a product and the List of its pictures for that product. The code below works fine but it returns only 1 picture of the product instead. I am having issues mapping the result of MySQL query to C# objects.
Here is what I have tried so far
public ProductModel GetProductDetail(uint product_id)
{
var cmd = this.MySqlDatabase.Connection.CreateCommand() as MySqlCommand;
cmd.CommandText = #"SELECT products.*, images.* FROM products LEFT JOIN images ON products.product_id= images.product_id WHERE products.product_id = #product_id LIMIT 0,1";
cmd.Parameters.AddWithValue("#product_id", product_id);
using (var reader = cmd.ExecuteReader())
while (reader.Read())
{
return new ProductModel()
{
product_id = reader.GetValue<UInt32>("product_id"),
subcategory_id = reader.GetValue<UInt32>("subcategory_id"),
product_name = reader.GetValue<String>("product_name"),
description = reader.GetValue<String>("description"),
is_recent = reader.GetValue<Boolean>("is_recent"),
is_popular = reader.GetValue<Boolean>("is_popular"),
is_available = reader.GetValue<Boolean>("is_available"),
price = reader.GetValue<Decimal>("price"),
overall_rating = reader.GetValue<Double>("overall_rating"),
views = reader.GetValue<UInt32>("views"),
people_rated = reader.GetValue<UInt32>("people_rated"),
date_posted = reader.GetValue<DateTime>("date_posted"),
Images = new List<ImagesModel>
{
new ImagesModel
{
imageurl = reader.GetValue<String>("imageurl"),
created_date = reader.GetValue<DateTime>("created_date")
}
}
};
}
return null;
}
Also below is the JSON result I get
{
"code": 1,
"message": "Product found",
"document": {
"product_id": 11,
"subcategory_id": 22,
"product_name": "Lead Guitar",
"description": "Unde dolor sed natus velit omnis doloribus consequatur adipisci quos quasi laboriosam optio aut beatae; cupiditate modi animi hic non qui consequatur, natus voluptatem quae ea quia est doloremque possimus.",
"is_recent": true,
"is_popular": false,
"is_available": false,
"price": 1942.51,
"overall_rating": 3,
"views": 520,
"people_rated": 350,
"date_posted": "2005-05-08T06:21:03",
"images": [
{
"imageurl": "http://www.thetehad.es/but/teerted/anne/ionhe.png",
"created_date": "2021-08-28T12:33:01"
},
.
.
.
// THERE SHOULD BE MORE IMAGES HERE BUT I AM GETTING ONLY ONE
]
}
}
Please what am I doing wrong here? Any assistance is highly appreciated.
There are few issues that need to point out.
ISSUES
First
SELECT products.*, images.* FROM products LEFT JOIN images ON products.product_id= images.product_id WHERE products.product_id = #product_id LIMIT 0,1
Your MYSQL query contains LIMIT 0,1, which means it will return the first row only.
Using LEFT JOIN for this query is not so correct, as by removing LIMIT 0,1, it returns 1 x n record(s) where n is the number of images record that has the same product_id.
Second
return new ProductModel()
{
Images = new List<ImagesModel>
{
new ImagesModel
{
imageurl = reader.GetValue<String>("imageurl"),
created_date = reader.GetValue<DateTime>("created_date")
}
}
};
You create new ProductModel() and assign Images with List<ImagesModel> that contains one ImagesModel object only.
SOLUTION
For first issue: Split the query into two and using two DataReader:
First DataReader will only query Product record based on ProductID
Second DataReader will query Image records based on ProductID
For second issue: Retrieve image records from second DataReader and using loop to create image object(s)
public ProductModel GetProductDetail(uint product_id)
{
ProductModel product = null;
using (var productCmd = this.MySqlDatabase.Connection.CreateCommand() as MySqlCommand)
{
productCmd.CommandText = #"SELECT * FROM products WHERE product_id = #product_id";
productCmd.Parameters.Add("#product_id", SqlDbType.int).Value = product_id;
using (var reader = productCmd.ExecuteReader())
{
while (reader.Read())
{
product = new ProductModel()
{
product_id = reader.GetValue<UInt32>("product_id"),
subcategory_id = reader.GetValue<UInt32>("subcategory_id"),
product_name = reader.GetValue<String>("product_name"),
description = reader.GetValue<String>("description"),
is_recent = reader.GetValue<Boolean>("is_recent"),
is_popular = reader.GetValue<Boolean>("is_popular"),
is_available = reader.GetValue<Boolean>("is_available"),
price = reader.GetValue<Decimal>("price"),
overall_rating = reader.GetValue<Double>("overall_rating"),
views = reader.GetValue<UInt32>("views"),
people_rated = reader.GetValue<UInt32>("people_rated"),
date_posted = reader.GetValue<DateTime>("date_posted")
};
}
}
}
if (product == null)
return null;
var imageList = new List<ImagesModel>();
using (var imageCmd = this.MySqlDatabase.Connection.CreateCommand() as MySqlCommand)
{
imageCmd.CommandText = #"SELECT * FROM images WHERE product_id = #product_id";
imageCmd.Parameters.Add("#product_id", SqlDbType.int).Value = product_id;
using (var reader = imageCmd.ExecuteReader())
{
while (reader.Read())
{
imageList.Add(new ImagesModel
{
imageurl = reader.GetValue<String>("imageurl"),
created_date = reader.GetValue<DateTime>("created_date")
});
}
}
}
product.Images = imageList;
return product;
}

How to save a List of objects to Firestore

I need to save my list of objects to Firestore database. Below is my code:
How I Create the List of object
private async void LoadPlazaListAndSummary()
{
_plazaList = await _dc.GetPlazas();
foreach(var item in _plazaList)
{
var par = new ParameterManualTags
{
Plaza = item.Code,
Lane = item.Lane,
DateTo = System.DateTime.Now,
DateFrom = System.DateTime.Today
};
var manualCount = await _dc.GetManualAndTransactionCount(par);
var model = new Summary
{
Name = item.Name,
Lane = item.Lane,
Code = item.Code,
DateRun = System.DateTime.Now,
ManualAverage = 100.00,
ManualCount = manualCount[0],
ReadCount = 1,
TotalTransaction = manualCount[1],
Type = item.Type,
Plaza = item,
DateFrom = par.DateFrom,
DateTo = par.DateTo,
RfidAddress = item.ReaderIpAddress,
IsDedicated = item.IsDedicated ? "Dedicated" : "Mixed"
};
model.ManualAverage = Math.Round(ComputeManualPercentage(model), 2);
_summaryList.Add(model);
DgSummary.Items.Add(model);
}
}
This is my sample to save data to Firestore:
public void SetData()
{
if (_isConnected)
{
try
{
var doc = _database.Collection("MyCollection").Document("myDocument");
Dictionary<string, object> data = new Dictionary<string, object>()
{
{"FirstName", "MyFirstName"},
{"LastName", "MyLastName"},
{"PhoneNumber", "PhoneNumber"}
};
var x = doc.SetAsync(data);
Console.WriteLine("Saved");
}
catch (Exception ex)
{
Console.WriteLine($#"An error occured in saving the data: {ex.Message}");
}
}
}
Using my sample code, I can insert one at a time to Firestore but, I do not know how to save a list of objects to Firestore.

How to retrieve the data from mongodb in json format using c# entity framework

I am retrieving the data from mongodb.it is coming as bson document.
when i am converting it to json it throws system out of memory exception because of bulk data (>100 000) is coming from mongodb.
Is it possible to retrieve the data from mongodb in json format directly?
public object getFrequencyQuestionData1(int id)
{
var StudyId = (from ST in _context.Study_Team
where ST.Emp_Id == id
select (ST.Study_Id).ToString()).ToList();
var connectionString = "mongodb://localhost:27017";
MongoClient client = new MongoClient(connectionString);
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase("FormDataBase");
MongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>("FrequencyQuestionForm");
var array = new BsonArray(StudyId.ToArray());
var query = Query.In("data.formList.IdentificationDetails.Study_Id", array);
var myLists = collection.Find(query);
myLists.SetFields(Fields.Include("_id","data.formList.IdentificationDetails.Study_Id", "data.formList.IdentificationDetails.Study_Name", "data.formList.IdentificationDetails.Volunteer_Id", "data.formList.IdentificationDetails.Form_Id","data.formList.IdentificationDetails.Form_Name", "data.formList.IdentificationDetails.Status", "data.formList.IdentificationDetails.Group_Id", "data.formList.IdentificationDetails.Visit_No","data.formList.IdentificationDetails.Created_Emp_Id", "data.formList.IdentificationDetails.Updated_Emp_Id"));
var items = myLists.ToList();
string document = items.ToJson();
JToken token = JToken.Parse(document);
var jObject = JObject.FromObject(new { formdata = token });
JArray sizes = (JArray)jObject["formdata"];
ArrayList SplittedData = new ArrayList();
for (int i = 0; i < sizes.Count(); i++)
{
JValue _id = (JValue)sizes[i]["_id"];
JObject sampledata = (JObject)sizes[i]["data"];
JArray sampledata2 = (JArray)sampledata["formList"];
JArray sampledata3 = (JArray)sampledata2[0]["IdentificationDetails"];
sampledata3[0]["id"] = _id;
int? Visit_No = (int?)sampledata3[0]["Visit_No"];
int? Group_Id = (int?)sampledata3[0]["Group_Id"];
int? Study_Id = (int?)sampledata3[0]["Study_Id"];
int? Form_Id = (int?)sampledata3[0]["Form_Id"];
int CreatedEmp_Id =(int)sampledata3[0]["Created_Emp_Id"];
var Visit_No1 = (from SS in _context.Study_Schedule
join SV in _context.Study_Visits
on new { SS.Study_Id, SS.Visit_No } equals
new { SV.Study_Id, SV.Visit_No }
//on SS.Study_Id equals SV.Study_Id && SS.Visit_No equals SV.Visit_No
where SS.Study_Id == Study_Id && SS.Visit_No == Visit_No && SS.Form_Id == Form_Id
select SV.Visit_Description).FirstOrDefault();
var Created_Emp_Id = (from US in _context.User
where US.Emp_Id == CreatedEmp_Id
select US.Emp_Name).FirstOrDefault();
sampledata3[0]["Created_Emp_Id"] = Created_Emp_Id;
if (Group_Id == null)
{
sampledata3[0]["Diet_Group"] = "";
}
else
{
var StudyGroup = (from SG in _context.Study_Group
where SG.Group_Id == Group_Id
select new
{
Group_Description = SG.Group_Description,
}).FirstOrDefault();
if (StudyGroup == null)
{
sampledata3[0]["Diet_Group"] = "";
}
else
{
sampledata3[0]["Diet_Group"] = StudyGroup.Group_Description.ToString();
}
}
sampledata3[0]["Visit"] = Visit_No1;
sampledata3[0]["Created_Emp_Id"] = Created_Emp_Id;
var sampledata4 = (JObject)sampledata3[0];
SplittedData.Add(sampledata4);
}
var jObject1 = JObject.FromObject(new { formdata = SplittedData});
return jObject1;
}

Create seed data from sql script

I'm using ORM in my project. Currently seed data is taken from sql scripts but I would like to create seed data basing on my c# code. For example, I have sql:
SET IDENTITY_INSERT [dbo].[State] ON
INSERT INTO [dbo].[State] ([Id], [Code], [Name]) VALUES (1, N'AL', N'Alabama')
INSERT INTO [dbo].[State] ([Id], [Code], [Name]) VALUES (2, N'AK', N'Alaska')
SET IDENTITY_INSERT [dbo].[State] OFF
And instead of it I want to have a string:
new List<State>
{
new State { Id = 1, Code = "AL", Name = "Alabama" },
new State { Id = 2, Code = "AK", Name = "Alaska" }
};
How can I achieve it?
For INSERT statements (as you said you need seed) you can create helper method like this:
public static List<State> ParseSqlScript(string sqlScriptPath)
{
using (var reader = new StreamReader(sqlScriptPath))
{
var sqlScript = reader.ReadToEnd();
var pattern = #"INSERT INTO \[dbo\].\[State\] \(\[Id\], \[Code\], \[Name\]\) VALUES (\(.*?\))";
var regex = new Regex(pattern);
var matches = regex.Matches(sqlScript);
var states = new List<State>();
foreach (Match match in matches)
{
var values = match.Groups[1].Value.Split(new [] { '(', ',',' ',')' }, StringSplitOptions.RemoveEmptyEntries);
var id = int.Parse(values[0]);
var code = values[1].Substring(2, values[1].Length - 3);
var name = values[2].Substring(2, values[2].Length - 3);
foreach (var value in values)
{
var state = new State() { Id = id, Code = code, Name = name };
states.Add(state);
}
}
return states;
}
}
If you also need other CRUD statements you will probably need to get acquainted with some SQL Parser, maybe the Microsoft.SqlServer.SMO.
Try to add the following code, I assume you are working with entity framework:
List<State> states = new List<State>()
{
new State { Id = 1, Code = "AL", Name = "Alabama" },
new State { Id = 2, Code = "AK", Name = "Alaska" }
};
StateDBEntities context = new StateDBEntities();
foreach (State state in states)
{
context.State.Add(state);
}
context.SaveChanges();
List<State> states = new List<State>();
using (SqlConnection connection = new SqlConnection("conn_string"))
{
string query = "SELECT Id, Code, Name FROM State";
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
State state = new State { Id = (int)reader["Id"], Code = reader["Code"].ToString(), Name = reader["Name"].ToString() };
states.Add(state);
}
}
}
}
Call the select query(here I'm writing the query, but it should be avoided, you can use Stored Procedure). Get all columns using ExecuteReader and add all the rows to list one by one.

C# Custom Json using JSON.NET from dataset or datatable

Can somebody help me to get the custom JSON string from datatable using C#.
I need something like below.I am able to achive this by using for each loop.
[
{"message": {"alert": "Address Updated"},"target": {"userIds": ["BKAC7759"]}},
{"message": {"alert": "Payment Processed"},"target": {"userIds": ["BKAC7759"]}},
{"message": {"alert": "Notice Sent"},"target": {"userIds": ["BKAC7759"]}}
]
But is there any way i can make it in simple way. My datatable contains values for "alert" and "userIds"
private string GetJsonData(int numberofRecords)
{
// OleDbConnection conn = new OleDbConnection(connectionString);
try
{
DataTable Test = new DataTable("A");
Test.Columns.Add("alert");
Test.Columns.Add("userIds");
Test.Rows.Add("Address Updated", "BKAC7759");
Test.Rows.Add("Payment Made", "BKAC7759");
//Test.Rows.Add("Check Processed", "MAND1884");
//Test.Rows.Add("Notice Mailed", "JAID3869");
//Test.Rows.Add("DL Suspended", "AOQU4798");
string jo = string.Empty;
string com = ",";
int i = 0;
int count = Test.Rows.Count;
string bracketright = "]";
string bracketleft = "[";
foreach (DataRow row in Test.Rows)
{
if (i == 0)
{
jo = jo + bracketleft;
}
jo = jo + "{\"message\":{\"alert\":\"" + row[0].ToString() + "\"},\"target\":{\"userIds\":[\"" + row[1].ToString() + "\"]}}";
if (i != count - 1)
{
jo = jo + com;
}
else
{
jo = jo + bracketright;
}
i++;
}
return jo;
}
catch (Exception ex)
{
Logger.Error("GetJsonData(int numberofRecords): " + ex.Message);
return string.Empty;
}
finally
{
// always close the connection.
// conn.Close();
}
}
You can use Linq + DataTableExtensions (in namespace System.Data and system DLL System.Data.DataSetExtensions.dll) to transform your table into an enumerable of anonymous types, then serialize that to JSON with json.net.
I notice your "userIds" property is a JSON array. Do you want all the user userIds for a given alert to be combined? If so, you can use ToLookup to combine them:
var root = dataTable.AsEnumerable()
.ToLookup(r => r["alert"].ToString(), r => r["userIds"].ToString())
.Select(g => new { message = new { alert = g.Key }, target = new { userIds = g } });
var json = JsonConvert.SerializeObject(root);
If not, do:
var root = dataTable.AsEnumerable()
.Select(r => new { message = new { alert = r["alert"].ToString() }, target = new { userIds = new [] { r["userIds"].ToString() } } });
var json = JsonConvert.SerializeObject(root);
For the following table:
var dataTable = new DataTable("A");
dataTable.Columns.Add("alert");
dataTable.Columns.Add("userIds");
dataTable.Rows.Add("Address Updated", "BKAC7759");
dataTable.Rows.Add("Payment Made", "BKAC7759");
dataTable.Rows.Add("Address Updated", "MAND1884");
dataTable.Rows.Add("Payment Made", "MAND1884");
The first produces the following JSON:
[
{"message":{"alert":"Address Updated"},"target":{"userIds":["BKAC7759","MAND1884"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["BKAC7759","MAND1884"]}}
]
And the second produces the following:
[
{"message":{"alert":"Address Updated"},"target":{"userIds":["BKAC7759"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["BKAC7759"]}},
{"message":{"alert":"Address Updated"},"target":{"userIds":["MAND1884"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["MAND1884"]}}
]

Categories

Resources