How to fetch records without Duplicates using Linq - c#

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();
}
}

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));

How to aggregate data, pass and fail as final result?

I have a list of result either having or not having Data plus has Pass and Fail like below,
var results = new List<Result>
{
new Result{Data = new Data{Name = "A"}, Pass = 1, Fail = 0},
new Result{Data = new Data{Name = "B"}, Pass = 3, Fail = 1},
new Result{Pass = 1, Fail = 0}
};
I need to aggregate data and need this as final result output,
var finalResult = new FinalResult
{
Datas = new List<Data> { new Data { Name = "A" }, new Data { Name = "B" } },
TotalPass = 5,
TotalFail = 1,
Divident = 5/1
}
I tried something like below, but totalPass and totalfail, are not coming correct. Plus, how to aggregate Data?
int totalPass = 0;
int totalfail = 0;
var finalResult = new FinalResult();
foreach (var r in results)
{
totalPass += r.Pass;
totalfail += r.Fail;
}
finalResult.TotalFail = totalPass;
finalResult.TotalFail = totalfail;
finalResult.Divident = totalPass / totalfail;
Here are the two classes:
public class FinalResult
{
public List<Data> Datas { get; set; }
public int TotalPass { get; set; }
public int TotalFail { get; set; }
public int Divident { get; set; }
}
public class Result
{
public Data Data { get; set; }
public int Pass { get; set; }
public int Fail { get; set; }
}
public class Data
{
public string Name { get; set; }
}
You can achieve this easily using LINQ:
var finalResult = new FinalResult
{
Datas = results.Where(r => r.Data != null).Select(r => r.Data).ToList(),
TotalPass = results.Sum(r => r.Pass),
TotalFail = results.Sum(r => r.Fail)
};
// Beware of division by zero and integer division.
finalResult.Divident = finalResult.TotalPass / finalResult.TotalFail;
Notes:
You should probably check the value of TotalFail before the division to prevent division by zero.
As Groo mentioned in the comments, Divident should probably be declared as double and you should cast one of the parts to double unless you do want Integer Division.

Query MongoDB in C# using LINQ

I have simple class which represents fields in MongoDB document
class Measurement
{
public ObjectId id { get; set; }
public int s { get; set; }
public int[] p { get; set; }
public int dt { get; set; }
public int ml { get; set; }
}
I'm trying to get documents matching my conditions using
var collection = database.GetCollection<Measurement>(mongoCollectionName);
var query = from a in collection.AsQueryable<Measurement>()
where a.dt > 100
select a;
When where condition is removed i do receive all documents but with condition none. Response says there's no matching documents but there are (example dt=1538555)
query looks like this {aggregate([{ "$match" : { "dt" : { "$gt" : 100 } } }])}.
I build my example using response from this thread and mongodb documentation
MongoDB C# Aggregation with LINQ
I would be grateful with solving probably my stupid mistake
i don't use the c# driver directly anymore so my solution is using MongoDAL.
using System;
using System.Linq;
using MongoDAL;
namespace Example
{
class Measurement : Entity
{
public int s { get; set; }
public int[] p { get; set; }
public int dt { get; set; }
public int ml { get; set; }
}
class Program
{
static void Main(string[] args)
{
new DB("measurements");
var measurement1 = new Measurement
{
s = 10,
ml = 20,
dt = 100,
p = new int[] { 1, 2, 3, 4, 5 }
};
var measurement2 = new Measurement
{
s = 11,
ml = 22,
dt = 200,
p = new int[] { 1, 2, 3, 4, 5 }
};
measurement1.Save();
measurement2.Save();
var result = (from m in DB.Collection<Measurement>()
where m.dt > 100
select m).ToArray();
Console.ReadKey();
}
}
}

How to create json structure from list of data?

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..

how to create a json format using json.net in c#

I need a final json format as follows and that should be dynamic.
{
"product_items" :
[
{
"_at" : 1,
"product_id" : "999"
},
{
"_at" : 2,
"quantity" : 2.00
},
{
"_delete_at" : 3
}
]
}
How to create a json format as above in the code._at field is dynamic.sometimes it might be 2 and sometimes it might be 10.I dont have idea on to generate the json dynamically in c#.
class Test
{
public ProductItem[] product_items { get; set; }
class ProductItem
{
public int[] _at { get; set; }
public int[] _delete { get; set; }
public int[] quantity { get; set; }
public string[] product_id{get;set;}
}
}
i have create the the properties for json as above.
I'm using Newtonsoft library
Your class should look more like this:
public class ProductItem
{
public int _at { get; set; }
public string product_id { get; set; }
public double? quantity { get; set; }
public int? _delete_at { get; set; }
}
public class ProductItemObject
{
public List<ProductItem> product_items { get; set; }
}
A example on serializing :
List<ProductItem> list = new List<ProductItem>();
ProductItemObject o = new ProductItemObject { product_items = list };
var item1 = new ProductItem { _at = 1, product_id = "001" };
var item2 = new ProductItem { _at = 2, quantity = 2.00 };
var item3 = new ProductItem { _delete_at = 3 };
list.Add(item1);
list.Add(item2);
list.Add(item3);
string json = JsonConvert.SerializeObject(o, Formatting.Indented);
// json string :
// {
// "product_items": [
// {
// "_at": 1,
// "product_id": "001",
// "quantity": null,
// "_delete_at": null
// },
// {
// "_at": 2,
// "product_id": null,
// "quantity": 2.0,
// "_delete_at": null
// },
// {
// "_at": 0,
// "product_id": null,
// "quantity": null,
// "_delete_at": 3
// }
// ]
//}
An alternative full dynamic that gets u the same Json string without any model :
var jsonObject = new JObject();
dynamic objectList = jsonObject;
objectList.product_items = new JArray() as dynamic;
dynamic item = new JObject();
item._at = 1;
item.product_id = "999";
objectList.product_items.Add(item);
item = new JObject();
item._at = 2;
item.quantity = 2.00;
objectList.product_items.Add(item);
item = new JObject();
item._delete_at = 3;
objectList.product_items.Add(item);
string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObject, Formatting.Indented);
Well, if I understand you properly and you just need to be able to generate that json, the product list should be dynamic with maybe anonymous classes then:
public class Products
{
public Products()
{
product_items = new List<dynamic>();
}
public List<dynamic> product_items { get; set; }
}
products.product_items.Add(new { _at = 1, product_id = "999" });

Categories

Resources