How to create json structure from list of data? - c#

I want to create json structure with nested object from my list object.
This is my class:
public class Employee
{
public int EmployeeId { get; set; }
public int Skillssetpoints { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> Date { get; set; }
}
public class EmployeeModel
{
public int EmployeeId { get; set; }
public List<int> Skillssetpoints { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> Date { get; set; }
}
Records are like this:
EmployeeId SkillssetPoints Date
1 10 4/5/2016 16:12:12
2 12 3/5/2016 17:12:12
3 4 8/5/2016 8:12:12
4 20 1/5/2016 2:12:12
This is how i am getting data:
var data=context.Employee.Tolist();
After getting data i want to create this json structure from above data using EmployeeModel and return:
Expected Output:
{"Date":"8-5-2016 08:12:12","SkillssetPoints":[4,10,12,20]}
In Date field i would take Highest date so 8-5-2016 and SkillssetPoints will be order by ascending.
How to create this json structure with my EmployeeModel class??

Add a reference to the nuget package Newtonsoft.Json then use ...
string result = JsonConvert.Serialize(data);
It looks like you need to translate the data in your db to the model format by doing a projection first then serialize the result ...
var groupedData = data
.GroupBy(s => s.EmployeeId)
.OrderBy(s => s.Date)
.Select(g => new EmployeeModel {
EmployeeId = g.Key,
Name = g.First().Name,
Date = g.First().Date,
Skillssetpoints = g.Select(s => s.Skillssetpoints).OrderBy(i => i).ToList()
});
That should produce a collection of this model ...
public class EmployeeModel
{
public int EmployeeId { get; set; }
public List<int> Skillssetpoints { get; set; }
public string Name { get; set; }
public DateTime? Date { get; set; }
}
... when I do this ...
var data = new List<EmployeeModel> {
new EmployeeModel { EmployeeId = 1, Name = "Homer Simpson", Skillssetpoints = new List<int> { 1,2,3,4 }, Date = DateTime.Now },
new EmployeeModel { EmployeeId = 2, Name = "Marge Simpson", Skillssetpoints = new List<int> { 1,2,3,4 }, Date = DateTime.Now },
new EmployeeModel { EmployeeId = 3, Name = "Lisa Simpson", Skillssetpoints = new List<int> { 1,2,3,4 }, Date = DateTime.Now },
new EmployeeModel { EmployeeId = 4, Name = "Bart Simpson", Skillssetpoints = new List<int> { 1,2,3,4 }, Date = DateTime.Now }
};
var result = JsonConvert.SerializeObject(data);
I get this output ...
[
{
"EmployeeId": 1,
"Skillssetpoints": [1,2,3,4],
"Name": "Homer Simpson",
"Date": "2016-04-05T11:42:09.9126748+01:00"
},
{
"EmployeeId": 2,
"Skillssetpoints": [1,2,3,4],
"Name": "Marge Simpson",
"Date": "2016-04-05T11:42:09.9126748+01:00"
},
{
"EmployeeId": 3,
"Skillssetpoints": [1,2,3,4],
"Name": "Lisa Simpson",
"Date": "2016-04-05T11:42:09.9126748+01:00"
},
{
"EmployeeId": 4,
"Skillssetpoints": [1,2,3,4],
"Name": "Bart Simpson",
"Date": "2016-04-05T11:42:09.9126748+01:00"
}
]

Use newton JSON,it is available on NuGet and code is extremely easy.
using Newtonsoft.Json;
var jsonList = JsonConvert.SerializeObject(context.Employee.Tolist());
Cheers

Select your required records by grouping on particular field and then prepare the anonymous object in required pattern and serialize it for final results,
var models = (from em in employeeModels
group em by em.ID into g
select new
{
Id = g.Key,
maxDate = g.Max(p => p.Date)
}).ToList();
var result = new
{
date = prices.Max(p => p.maxDate),
SkillssetPoints = prices.Select(p => p.Id).ToList()
};
var json = JsonConvert.SerializeObject(result);
You will get the json in the pattern like
{
"date": "2016-04-05T16:39:54.8420979+05:30",
"SkillssetPoints": [
1,
2,
3
]
}

Use Newton JSON from Nuget Package and try This code
List lstEmp = new List();
for (int i = 1; i <= 4; i++)
{
Employee emp = new Employee();
emp.EmployeeId = i;
emp.Name = "Name" + i;
emp.Skillssetpoints = i + 1;
emp.Date = DateTime.Now.AddDays(i);
lstEmp.Add(emp);
}
var data = lstEmp;
var result = new EmployeeModel
{
Date = data.Max(p => p.Date),
Skillssetpoints = data.Select(p => p.Skillssetpoints).ToList()
};
var JsonData = JsonConvert.SerializeObject(new
{
Date = result.Date,
Skillssetpoints = result.Skillssetpoints
});
Cheers

1) Install Newtonsoft.Json package using NuGet
2) add namespace on top
using Newtonsoft.Json;
3) Add [JsonIgnore] on top of Model class properties which you don't want to include in json conversion
public class Employee
{
public int EmployeeId { get; set; }
public int Skillssetpoints { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> Date { get; set; }
}
public class EmployeeModel
{
[JsonIgnore]
public int EmployeeId { get; set; }
public List<int> Skillssetpoints { get; set; }
[JsonIgnore]
public string Name { get; set; }
public Nullable<System.DateTime> Date { get; set; }
}
4) Final code is below
var data = new List<Employee>();
data.Add(new Employee { EmployeeId = 1, Skillssetpoints = 10, Date = Convert.ToDateTime("4/5/2016 16:12:12") });
data.Add(new Employee { EmployeeId = 2, Skillssetpoints = 12, Date = Convert.ToDateTime("3/5/2016 17:12:12") });
data.Add(new Employee { EmployeeId = 3, Skillssetpoints = 4, Date = Convert.ToDateTime("8/5/2016 8:12:12") });
data.Add(new Employee { EmployeeId = 4, Skillssetpoints = 20, Date = Convert.ToDateTime("1/5/2016 2:12:12") });
var highestDate = data.OrderByDescending(e => e.Date).First().Date;
var skillssetpointsList = data.Select(e => e.Skillssetpoints).ToList();
EmployeeModel employeeModel = new EmployeeModel()
{
Date = highestDate,
Skillssetpoints = skillssetpointsList
};
string jsonString = JsonConvert.SerializeObject(employeeModel);
Now, jsonString = {"Skillssetpoints":[10,12,4,20],"Date":"2016-05-08T08:12:12"}

You may try to create a new object and serialize as below:
var result = JsonConvert.Serialize (new {
Date = context.Employee.Max(e => e.Date),
SkillssetPoints = context.Employee.Select(e => e.SkillssetPoints)
}));

i think you can try this
it works fine with me.
public ActionResult GetCitiesWithBranches(int regionID)
{
var cities =
_context.Cities.Where(e => e.RegionCode == regionID)
.Select(e => new { ID = e.CityCode, Name = e.Name })
.ToList();
return Json(new { cities = cities });
}
and in the view i am using that:
var json = { regionID: data };
$.ajax({
type: "POST",
url: '#Url.Action("GetCitiesWithBranches", "Admin")',
data: json,
dataType: "json",
error: function (xhr, status, error) {
//alert("error routine");
},
success: function (res) {
if (res.cities) {
}
}
});
Hope that will help..

Related

Mongodb C# Update element in an multiple array with multiple values

I want to update the single document in collection with the guid as filter and update value is cityType. Every guid has different citytype here i have used 3 types it may be more.
So please give a right implementation using c# code.
Models:
public class Country
{
[BsonId]
public ObjectId Id { get; set; }
public int CountryId {get; set; }
public IEnumerable<States> States { get; set; }
}
public class States
{
public Guid Guid { get; set; }
public CityType CityType { get; set; }
}
Enum CityType
{
Unknown = 0,
Rural = 1,
Urban = 2
}
Existing Collection:
{
"_id": ObjectId("6903ea4d2df0c5659334e763"),
"CountryId": 200,
"States": [
{
"Guid": "AFCC4BE7-7585-5E46-A639-52F0537895D8",
"CityType": 0,
},
{
"Guid": "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
"CityType": 0,
}
}
Input:
List<States>()
{
new States()
{
Guid = "AFCC4BE7-7585-5E46-A639-52F0537895D8",
CityType = CityType.Rural
},
new States()
{
Guid = "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
CityType = CityType.Urban
}
}
Expected:
{
"_id": ObjectId("6903ea4d2df0c5659334e763"),
"CountryId": 200,
"States": [
{
"Guid": "AFCC4BE7-7585-5E46-A639-52F0537895D8",
"CityType": 1,
},
{
"Guid": "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
"CityType": 2,
}
}
This is the method I have tried:
public async Task<bool> UpdateType(int countryId, IEnumerable<States> states)
{
var collection = connectionFactory.GetCollection<Country>(collectionName);
var cityTypes = states.Select(x => x.CityType);
var filter = Builders<Country>.Filter.Empty;
var update = Builders<Country>.Update.Set("States.$[edit].CityType", cityTypes);
var arrayFilters = new List<ArrayFilterDefinition>();
foreach (var state in states)
{
ArrayFilterDefinition<Country> optionsFilter = new BsonDocument("state.Guid", new BsonDocument("$eq", state.Guid));
arrayFilters.Add(optionsFilter);
}
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
var result = await collection.UpdateOneAsync(filter, update, updateOptions);
return result;
}
hope all details I have added here. Thanks in advance.
You don't have to loop through it:
Let's say you have a Class1 like this:
class Question : AuditableEntity {
public string Text { get; set; }
public List<string> Tags { get; set; } = new List<string>();
so you just say:
await collection.UpdateOneAsync(
someFilter,
Builders<Class1>.Update
.Set(f => f.Text, request.Question.Text)
.Set(f => f.Tags, request.Question.Tags));

Group by multiple column into object and related lists

After searching i couldn't link any answer found on this site to my issue
i have the following class
I have the following classes
public class Site
{
public string Name { get; set; }
public string Stauts { get; set; }
public string Demo { get; set; }
public List<Data> Datas { get; set; }
}
public class Data
{
public string IPT { get; set; }
public string Currency { get; set; }
public double Amount { get; set; }
}
I got data from external service in this format
"Name": "TcR",
"Stauts": "ACT",
"Demo": "BYD",
"IPT": "CATS",
"Currency": "EUR",
"Amount": "58.01",
"Name": "TcR",
"Stauts": "ACT",
"Demo": "BYD",
"IPT": "ROS",
"Currency": "USD",
"Amount": "25.01",
"Name": "TcR",
"Stauts": "ACT",
"Demo": "BYD",
"IPT": "SAP",
"Currency": "EUR",
"Amount": "44.01",
How can i transform this data to have one site and all related Data object in a list?
what i did
var result = from d in Loc
group d by new
{
Name = d.Name,
Stauts = d.Stauts,
Demo = d.Demo,
}
into g
select new Site
{
Name = g.Key.Name,
Stauts = g.Key.Stauts,
Demo = g.Key.Demo,
Datas = g.ToList()/// ==> error here
};
Assuimng you have that values in a list named _list, here's what you could do:
var grouped = _list
.GroupBy(item => new { item.Name, item.Status, item.Demo })
.Select(g => new Site()
{
Name = g.Key.Name,
Status = g.Key.Status,
Demo = g.Key.Demo,
Datas = g.Select(groupItem => new Data()
{
IPT = groupItem.IPT,
Currency = groupItem.Currency,
Amount = groupItem.Amount,
}).ToList(),
})
.ToArray();

How to fetch records without Duplicates using Linq

Hi can someone assist please,i have a list that contain my promotions codes and in the list i would like to return only promotion codes that appear once i.e dont have duplicates,please see below data from JSON,i would like to return Promotion code A123 and B500 and store them in another list.
[
{
"PromCode": "A123",
"Priority": 1,
"offer": "Win a Free Cap",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
{
"PromCode": "A100",
"Priority": 1,
"offer": "Win a perfume",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
{
"PromCode": "A100",
"Priority": 2,
"offer": "Win a Phone pouch",
"StartDte": "2020-09-11T00:16:23.184Z",
"endDte": "2020-10-10T17:16:23.184Z",
},
{
"PromCode": "B500",
"Priority": 1,
"offer": "Win a free router",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
]
I have a list that contains all this promotion code as seen below
var existingProms = await _Repo.GetAllPromCodes(promCodeList);
i tried to get ones that appear once in the list like this
var appearOnce = existingProms.Count(x => existingBnplIndicators.Contains(x.PromCode)).ToList()<2;
var appearOnce = existingProms.where(x=> x.PromCode.Count()).ToList()<2;
But this did not work,there is 0 results returned,could someone show how to get my two Proms A123,B500 into my appearOnce lis.Thankst
You can use GroupBy to get all the results grouped by PromoCode. Then, filter the results based on the number of items each group has to only show when Count() == 1.
Something like this perhaps,
public class Class1
{
public string PromCode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDte { get; set; }
public DateTime endDte { get; set; }
}
var obj = JsonConvert.DeserializeObject<List<Class1>>(json);
var singlesOnly = obj.GroupBy(x => x.PromCode).Where(y => y.Count() == 1);
You should compare desired objects only by promcode implicitly. Take look how Equals and GetHashCode() works.
using System;
using System.Collections.Generic;
using System.Linq;
namespace test
{
public class TestObj : IEquatable<TestObj>
{
public string Promocode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDate { get; set; }
public DateTime endDate { get; set; }
public override int GetHashCode() => this.Promocode.GetHashCode();
public bool Equals(TestObj other) => Promocode.Equals(other.Promocode);
}
class Program
{
static void Main(string[] args)
{
var a = new TestObj()
{
Promocode = "1",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var b = new TestObj()
{
Promocode = "1",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var c = new TestObj()
{
Promocode = "2",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var list = new List<TestObj>()
{
a,
b,
c
};
var uniqueOnly = list.Distinct();
foreach (var item in uniqueOnly)
{
Console.WriteLine(item.Promocode);
}
}
}
}
First define class items-
public string PromCode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDte { get; set; }
public DateTime endDte { get; set; }
Then take multiple items in list and use distinct() function to remove duplicate values-
static void Main(string[] args)
{
List<TestClass> list = new List<TestClass>()
{
new TestClass(){PromCode="A123",Priority=1,offer="Win a Free
Cap",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-10)},
new TestClass(){PromCode="A100",Priority=1,offer="Win a
perfume",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-
10)},
new TestClass(){PromCode="A100",Priority=2,offer="Win a Phone
pouch",StartDte=new DateTime(2020-09-11),endDte=new DateTime(2020-10-10)},
new TestClass(){PromCode="B500",Priority=1,offer="Win a free
router",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-10)}
};
var finalList = list.Select(b => b.PromCode).Distinct().ToList();
foreach(var item in finalList)
{
Console.WriteLine(item + "");
}
Console.Read();
}
}

How to get the value for complex object from given complex key using c#

I have the following JSON.
public class Code
{
public string ID { get; set; }
}
public class Country
{
public string CountryID { get; set; }
}
public class Complex
{
public Country Country { get; set; }
public Code Code { get; set; }
public string cText { get; set; }
}
public List<Complex> GetData()
{
List<Complex> Data = new List<Complex>();
Data.Add(new Complex() { Country = new Country() { CountryID = "Australia" }, Code = new Code() { ID = "AU" }, cText = "Australia" });
Data.Add(new Complex() { Country = new Country() { CountryID = "Bermuda" }, Code = new Code() { ID = "BM" }, cText = "Bermuda" });
Data.Add(new Complex() { Country = new Country() { CountryID = "Canada" }, Code = new Code() { ID = "CA" }, cText = "Canada" });
Data.Add(new Complex() { Country = new Country() { CountryID = "France" }, Code = new Code() { ID = "FR" }, cText = "France" });
return Data;
}
I need to get the value of CountryID from the given complex key ("Country.CountryID").
I have tried to get the value using the TryGetValue method in c#. It is doesn't work.
I think I need to split the key and process the Complex JSON and find the nested result.
Could you please suggest how to get the value for the complex object from the given complex key?
It can be done via LINQ like this
var codeIdToFind = "AU";
var result = data.Where(c => c.Code.ID.Equals(codeIdToFind, StringComparison.OrdinalIgnoreCase))
.Select(x => x.Country.CountryID)
.FirstOrDefault();

Convert flat db row data to nested typed objects linq

I'm getting the results of a sql outer join as flat results in an IEnumerable, and would like to convert them to nested typed objects in linq. From something like this:
[{id: 1, industryId: 1}, {id:1, industryId: 2}, {id:2, industryId: 1} etc..]
to something like this:
list of Company [{id: 1, list of Industry{industryId: 1, 2}, {id: 2, list of Industry{industryId: 1}}]
I'm currently trying a solution with GroupBy:
Companies = flatDbRows
.GroupBy(
row => row.CompanyId,
(key, value) => new CompanyModel
{
CompanyId = value.First().CompanyId,
CompanyName = value.First().CompanyName,
Industries = value
.GroupBy(
row => new { row.IndustryId, row.Industry },
(k, v) => new IndustryModel() { IndustryId = k.IndustryId, Name = k.Industry }
)
.Where(x => x.IndustryId != 0)
.ToList(),
}).ToList();
}
but it doesn't feel great, especially with all the value.First() I'm using to get the values that only belong to each grouped company. Is there something more appropriate? Group join sounded more like what I wanted, but I'm having trouble understanding how to apply it to a single list. I'm open to using query syntax instead of the lambdas if that's easier.
I'm trying to go from this model (where company-related info will be duplicated for each outer joined industry result):
public class CompanyFlatDbRowsModel
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public int IndustryId{ get; set; }
public string Industry { get; set; }
}
to this:
public class CompanyModel
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public IEnumerable<IndustryModel> Industries { get; set; }
}
// FULL edit after providing your models
public class TestClass
{
public class CompanyModel
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public List<IndustryModel> Industires { get; set; }
}
public class IndustryModel
{
public int IndustryId { get; set; }
public string IndustryName { get; set; }
}
public class CompanyFlatDbRowsModel
{
public CompanyFlatDbRowsModel()
{
}
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public int IndustryId { get; set; }
public string Industry { get; set; }
}
[Fact]
public void Test()
{
var data = new List<CompanyFlatDbRowsModel>
{
new CompanyFlatDbRowsModel
{
CompanyId = 1,
CompanyName = "Company 1",
IndustryId = 1,
Industry = "Industry 1"
},
new CompanyFlatDbRowsModel
{
CompanyId = 1,
CompanyName = "Company 1",
IndustryId = 2,
Industry = "Industry 2"
},
new CompanyFlatDbRowsModel
{
CompanyId = 2,
CompanyName = "Company 2",
IndustryId = 3,
Industry = "Industry 3"
},
new CompanyFlatDbRowsModel
{
CompanyId = 2,
CompanyName = "Company 2",
IndustryId = 4,
Industry = "Industry 4"
},
};
var result = data.GroupBy(x => x.CompanyId)
.Select(x => new CompanyModel()
{
CompanyId = x.Key,
CompanyName = x.First().CompanyName,
Industires = x.Select(y=> new IndustryModel
{
IndustryName = y.Industry,
IndustryId = y.IndustryId
}).ToList()
}).ToList();
foreach (var item in result)
{
var text = $"Company id : {item.CompanyId}, industries : {string.Join(',',item.Industires.Select(x=>$"(name: {x.IndustryName}, id: {x.IndustryId})"))}";
Debug.WriteLine(text);
}
}
}
output:
Company id : 1, industries : (name: Industry 1, id: 1),(name: Industry 2, id: 2)
Company id : 2, industries : (name: Industry 3, id: 3),(name: Industry 4, id: 4)
edit:
alternatively you can do as below, however the "first" thing still occurs somewhere, I have tried also the GroupJoin but it doesn't really help in that case.
var otherResult = data.Select(x =>
new CompanyModel
{
CompanyId = x.CompanyId,
CompanyName = x.CompanyName,
Industires = data
.Where(y => y.CompanyId == x.CompanyId)
.Select(y => new IndustryModel
{
IndustryId = y.IndustryId,
IndustryName = y.Industry
}).ToList()
})
.GroupBy(y => y.CompanyId)
.Select(x => x.First())
.ToList();
edit:
one more approach without using "first"
var anotherResult = data.GroupBy(x => x.CompanyId)
.Select(x =>
{
var companyModel = new CompanyModel()
{
CompanyId = x.Key
};
companyModel.Industires = x.Select(y =>
{
companyModel.CompanyName = y.CompanyName; // assignign here occurs multiple times however with the same value
return new IndustryModel
{
IndustryId = y.IndustryId,
IndustryName = y.Industry
};
}).ToList();
return companyModel;
}).ToList();

Categories

Resources