modify items in a Generic List - c#

i cannot modify generic List with :
var x = (PaypalResponse)Session["PaypalResponse"]; // x.Response is my List
x.Response.ToList().Where(i => i.Id== 1).ForEach(s => s.Selected = true);
where am I doing wrong?
Thanks.

You could do this:
x.Response.Where(i => i.Id == 1).ToList().ForEach(s => s.Selected = true);
However, it's a bit of a waste of resources to construct a new list just for this one line of code. I'd recommend this instead:
foreach(var s in x.Response.Where(i => i.Id == 1))
{
s.Selected = true;
}
If you only want to update at most one item, you can do this instead:
var s = x.Response.FirstOrDefault(i => i.Id == 1);
if (s != null)
{
s.Selected = true;
}
And of course, if you know there will be one item to update, it's even easier:
x.Response.First(i => i.Id == 1).Selected = true;

Related

How do you call a function to an Linq List query that uses the exist function

I have this method with a linq statement below. I'm not a fan of multiple if statement and I'm trying to find what is the best way to not have these if statement and have a private method.
My field values is being set as such:
var fieldValues = await GetFields // then it's being passed to my method.
public static AppraisalContactBorrower BuildCoBorrower(List<LoanFieldValue> fieldValues) {
var coborrower = new AppraisalContactBorrower();
if (fieldValues.Exists(f => f.FieldId == "CX.OS.AO.COBORRNAME")) {
coborrower.Name = fieldValues.First(v => v.FieldId == "CX.OS.AO.COBORRNAME").Value;
}
if (fieldValues.Exists(f => f.FieldId == "CX.OS.AO.BORRCONTACTZIP")) {
borrower.Zip = fieldValues.First(v => v.FieldId == "CX.OS.AO.BORRCONTACTZIP").Value;
}
if (fieldValues.Exists(f => f.FieldId == "CX.OS.AO.BORRCONTACTZIP")) {
borrower.Zip = fieldValues.First(v => v.FieldId == "CX.OS.AO.BORRCONTACTZIP").Value;
}
What I'm trying to do is instead of this:
coborrower.Name = fieldValues.First(v => v.FieldId == "CX.OS.AO.COBORRNAME").Value;
Is having something similar to this.
if (fieldValues.Exists(f => f.FieldId == "CX.OS.AO.BORRCONTACTZIP")) {
coborrower.Name = SETVALUE("CX.OS.AO.BORRCONTACTZIP")}
First, try using Enumerable.ToDictionary to have the field values grouped by FieldId, then use IDictionary.TryGetValue to get the existing values:
public static AppraisalContactBorrower BuildCoBorrower(List<LoanFieldValue> fieldValues) {
var groupedFieldValues = fieldValues.ToDictionary(f => f.FieldId)
var coborrower = new AppraisalContactBorrower();
if (groupedFieldValues.TryGetValue("CX.OS.AO.COBORRNAME", out var name)) {
coborrower.Name = name.Value;
}
if (groupedFieldValues.TryGetValue("CX.OS.AO.BORRCONTACTZIP", out var zip)) {
borrower.Zip = zip.Value;
}
}
Using Dictionary makes it faster to check the appropriate field existence as it is O(1) and with TryGetValue you combine two operations into one (existence check + obtaining the value).
Your two last statements are almost identitical. The equivalent of :
if (groupedFieldValues.TryGetValue("CX.OS.AO.COBORRNAME", out var name)) {
coborrower.Name = name.Value;
}
is:
coborrower.Name = fieldValues.FirstOrDefault(v => v.FieldId == "CX.OS.AO.COBORRNAME")
?? coborrower.Name;
In the original code, coborrower.Name is not updated if the field doesn't exist in the list.

How to optimise foreach loop in entity framework in dot net core c#

I need to optimised this code, it takes half an hour more time to display data. I used this code: -
public IEnumerable<ParcelList> GetAll()
{
List<ParcelList> allData = new List<ParcelList>();
List<Parcel> allparcels = _context.Parcela.OrderByDescending(o => o.id).ToList();// Containing records 4,64,872 having 76 columns fields
foreach (Parcel item in allparcels)
{
ParcelList p = new ParcelList();
p.parcel = new ParcelName();
p.parcel.col1name = "";
p.parcel.col2name = "";
p.parcel.col3name = "";
p.parcel.col1 = item.col1;
p.parcel.col2 = item.col2;
p.parcel.col3 = item.col3;
p.parcel.col4 = item.col4;
p.parcel.col5 = item.col5;
try
{
p.parcel.CountryName = _context.Concelho
.Where(w => Convert.ToInt64(w.col1) == Convert.ToInt64(item.col1))
.Select(s => s.col1name)
.FirstOrDefault();
p.parcel.DistrictName = _context.Distrito
.Where(w => Convert.ToInt64(w.col2) == Convert.ToInt64(item.col2))
.Select(s => s.col2name)
.FirstOrDefault();
p.parcel.ParishName = _context.Freguesia
.Where(w => Convert.ToInt64(w.col3) == Convert.ToInt64(item.col3))
.Select(s => s.col3name)
.FirstOrDefault();
}
catch (Exception)
{
// I should never ever ever swallow exceptions
// I should never ever ever swallow exceptions
// I should never ever ever swallow exceptions
}
p.Explorer = _context.Explorer.AsNoTracking()
.Where(w => w.pid == item.id)
.Where(w1 => w1.VERSAO == item.VERSAO)
.ToList()
.ToArray();
p.Property = _context.Property.AsNoTracking()
.Where(w => w.pid == item.id)
.Where(w1 => w1.VERSAO == item.VERSAO)
.ToList()
.ToArray();
allData.Add(p);
}
return allData;
}
In this, the Table contains records 4,64,872 having 76 columns fields.
Please help!!

Change loop to Linq C#

One of my function in C# required me to filter some value.So, I try it by using a lot of loop in it. It works but doesn't look like effecient.Any idea on how to convert code below to LinQ?
Any help is appreciated.
var object1 = JsonConvert.DeserializeObject<List<string>>(object1json);
foreach (var item1 in table1)
{
if (item1.Code == InputCode)
{
for (int i = 0; i < object1.Count(); i++)
{
tempData temp = new tempData();
foreach (var item2 in item1.List)
{
if (item2.Code == object1[i])
{
temp.Code = item2.Code;
temp.Description = item2.Description;
}
}
if(temp.Code != null || temp.Description != null)
final.Add(temp);
}
}
}
If you want your code to be more efficient, as pointed out in the comments, converting it to Linq isn't really going to help. It's still the same logic, just written in a different way. If you're going for readability, it can be improved with just a few changes:
foreach (var item1 in table1.Where(i => i.Code == InputCode))
{
foreach (var code in object)
{
// This could be SingleOrDefault, I don't know if you have duplicates in the list or not
var item2 = item1.List.LastOrDefault(i => i.Code == code);
if(item2 != null)
{
final.Add(new tempData
{
Code = item2.Code,
Description = item2.Description,
});
}
}
}
If you convert the whole thing to Linq:
var final = table1.Where(i => i.Code == InputCode)
.SelectMany(item1 => object.Select(code => item1.List.LastOrDefault(i => i.Code == code))
.Where(item2 => item2 != null)
.Select(item2 => new tempData
{
Code = item2.Code,
Description = item2.Description,
})
.ToList();
Personally, I prefer the first option, as it's a bit easier to read.
I guess what you post is sample code instead of actual code otherwise it would be better to avoid keyword like object in C#. Anyway,
var final = table1.Where(item1 => item1.Code == InputCode)
.SelectMany(item1 => item1.List)
.Where(item2 => #object.Contains(item2.Code))
.Where(temp => temp.Code != null || temp.Description != null)
.Select(item2 => new tempData()
{
Code = item2.Code,
Description = item2.Description
});

linq C# why the value change

Easily say, why those two qqq are different in the breakpoint?
TodayInformation and YesterdayInformation actually are type of List<MyClass>
It is very strange that as usually, YesterdayInformation couldn't be any changes through this part, but actually YesterdayInformation is updated as TodayInformation I never use any pointer or reference?
var qqq = YesterdayInformation;
var TodayInformation = YesterdayInformation;
TodayInformation.Select(o =>
{
o.Signal = SignalpairList.Where(p => p.pair == o.pair).Select(p => p.signal).First();
o.SigmaMove = SigmaMovepairList.Where(p => p.pair == o.pair).Select(p => p.SigmaMove).First();
o.Date = Today;
return o;
}).ToList();
qqq = YesterdayInformation;
Because TodayInformation and YesterdayInformation are the same reference. You have a query of TodayInormation, but you modified each item in .Select method. Your query does something like:
var TodayInformation = YesterdayInformation;
foreach(var o in TodayInformation)
{
//you are modifying each item of TodayInformation collection
o.Signal = SignalpairList.Where(p => p.pair == o.pair).Select(p => p.signal).First();
o.SigmaMove = SigmaMovepairList.Where(p => p.pair == o.pair).Select(p => p.SigmaMove).First();
o.Date = Today;
}
I think you want this:
var TodayInformation = YesterdayInformation;
var result = TodayInformation.Select(o => new
{
Signal = SignalpairList.Where(p => p.pair == o.pair).Select(p => p.signal).First(),
SigmaMove = SigmaMovepairList.Where(p => p.pair == o.pair).Select(p => p.SigmaMove).First(),
Date = Today
}).ToList();
This query loops over the collection TodayInformation, loads the data to an anonymous object without modifying the original item, and set the result list into a variable.
I'm not exactly sure what you are saying or asking, but the code as-in is basically a loop updating the items.
This would be a lot clearer, and equivalent to your code.
var TodayInformation = YesterdayInformation;
foreach (var oin TodayInformation) {
o.Signal = SignalpairList.Where(p => p.pair == o.pair).Select(p => p.signal).First();
o.SigmaMove = SigmaMovepairList.Where(p => p.pair == o.pair).Select(p => p.SigmaMove).First();
o.Date = Today;
}

MVC4 Linq Query Optimisation

I have the below code which works but I do not feel this is the best way to achieve the result. I am looking at optimising my code. Any suggestions of a better option will be appreciated. sub is a subcategory which is nullable.
[AllowAnonymous]
public ActionResult _relatedgrps(string cat, string sub)
{
if (!string.IsNullOrWhiteSpace(sub)){
var pgs = db.Pages
.Where(u=>u.MetaNoSearch==false)
.Where(u => u.PaOk == true && u.Category.Name == cat && u.SubCategory.CatName == sub)
.OrderByDescending(u => u.PaCreatedOn);
return PartialView(pgs.ToList());
}else{
var pgs = db.Pages
.Where(u=>u.MetaNoSearch==false)
.Where(u => u.PaOk == true && u.Category.Name == cat )
.OrderByDescending(u => u.PaCreatedOn);
return PartialView(pgs.ToList());
}}
Linq IEnumerables can be additive and the query will only be executed when enumerated for the first time (like calling .ToList()). So you should be able to do something like this:
var pgs = db.Pages
.Where(u => u.MetaNoSearch == false &&
u.PaOk == true &&
u.Category.Name == cat);
if (!string.IsNullOrWhiteSpace(sub))
{
pgs = pgs.Where(u => u.SubCategory.CatName == sub);
}
return PartialView(pgs.OrderByDescending(u => u.PaCreatedOn).ToList());
Create an object to query it. To improve it, you also could remove it boolean comparations because they are conditions.
var query = db.Pages.Where(u => !u.MetaNoSearch && u.PaOk && u.Category.Name == cat);
if (!string.IsNullOrWhiteSpace(sub))
query = query.Where(u => u.SubCategory.CatName == sub);
query = query.OrderByDescending(u => u.PaCreatedOn);
return PartialView(query.ToList());
#user3021830 - be careful with String.IsNullOrWhitespace, you cannot use that in a database query. You could do String.IsNullOrWhitespace(sub), but not String.IsNullOrWhitespace(u.*).
I'd avoid any conditionals in the query because that will likely result in a case statement in the SQL.
To produce the best SQL I'd do something like this:
var pgs = db.Pages.Where(u => u.MetaNoSearch == false)
.Where(u => u.PaOk == true)
.Where(u => u.Category.Name == cat);
if (!string.IsNullOrWhiteSpace(sub))
{
pgs = pgs.Where(u => u.SubCategory.CatName == sub);
}
var result = pgs.OrderByDescending(u => u.PaCreatedOn).ToList();

Categories

Resources