Every time I run this code, certlist reads in the first set of values and writes them successfully to the list. When it runs through the loop again the next set of values overwrites the first one and creates a second one. The end result is two identically values inside the list.
Any help with why it would overwrite the first value and how to fix it would be great.
foreach (var certcard in xdoc.Root.Element("Diver").Element("Certifications").Elements("Certification_Card"))
{
cert.Level = certcard.Element("Level").Value;
cert.Agency = certcard.Element("Agency").Value;
cert.Number = certcard.Element("Number").Value;
cert.Date = Convert.ToDateTime(certcard.Element("Date").Value);
certlist.Add(cert);
}
Your original code was only missing the declaration of cert:
foreach (var certcard in xdoc.Root.Element("Diver").Element("Certifications")
.Elements("Certification_Card"))
{
var cert = new Cert();
cert.Level = certcard.Element("Level").Value;
cert.Agency = certcard.Element("Agency").Value;
cert.Number = certcard.Element("Number").Value;
cert.Date = Convert.ToDateTime(certcard.Element("Date").Value);
certlist.Add(cert);
}
Similarly, you could do this without a loop using Linq:
certlist.AddRange(xdoc.Root.Element("Diver")
.Element("Certifications")
.Elements("Certification_Card")
.Select(c => new Cert
{
Level = c.Element("Level").Value,
Agency = c.Element("Agency").Value,
Number = c.Element("Number").Value,
Date = Convert.ToDateTime(c.Element("Date").Value)
}));
Try this :
foreach (var certcard in xdoc.Root.Element("Diver").Element("Certifications")
.Elements("Certification_Card"))
{
certlist.Add(new Cert()
{
Level = certcard.Element("Level").Value,
Agency = certcard.Element("Agency").Value,
Number = certcard.Element("Number").Value,
Date = Convert.ToDateTime(certcard.Element("Date").Value)
});
}
Related
I'm trying to insert a new record from TPOSTransaction and TPOSTransactionDetail
The code below is from an event in my class:
_posTransaction = new TPostransaction();
_posTransactionDetail = new TPostransactionDetail();
_posTransactionDetails = new List<TPostransactionDetail>();
_posTransaction.UserId = _user.Id;
_posTransaction.Total = Convert.ToDecimal(txtOrderTotal.Text);
_posTransaction.ChangeDue = Convert.ToDecimal(txtChangeDue.Text);
_posTransaction.AmountPaid = Convert.ToDecimal(txtAmountPaid.Text);
_posTransaction.TransactionDate = DateTime.Now;
foreach (ListViewItem orders in lvOrders.Items)
{
_posTransactionDetail.ItemId = Convert.ToInt32(orders.SubItems[1].Text);
_posTransactionDetail.Quantity = Convert.ToInt32(orders.SubItems[3].Text);
_posTransactionDetail.Subtotal = Convert.ToDecimal(orders.SubItems[4].Text) * Convert.ToDecimal(orders.SubItems[3].Text);
_posTransactionDetails.Add(_posTransactionDetail);
}
_posTransaction.TPostransactionDetail = _posTransactionDetails;
_pos.Add(_posTransaction); //method from a class
This is where I save the record:
When I try to debug, POSTransaction.TposTransactionDetail have 2 records since it's what I added from the list
//this is my primary concern
var posTransaction = dbContext.TPostransaction.Add(POSTransaction);
dbContext.TPostransactionDetail.AddRange(POSTransaction.TposTransactionDetail);
dbContext.SaveChanges();
This saves the record of TPosTransaction and TPosTransactionDetail, but the detail that is being saved is only one, instead of 2. I tried removing the AddRange part it still saves a single record in my TposTransactionDetail.
on you foreach you need to create new instance of TPostransactionDetail, you are just reusing the instance on the top of your code.
I'm using foreach to transfer data from list to another but when adding value updated automatically to last value added. For example:
list1 = [1,2,3]
list2 = new List<Model>()
foreach(var item in list1) {
list2.Add(item)
}
the result in list2 is [ 3, 3, 3]
Actually example is below :
var _sizes = new List<ProductsSize>();
var _size = new ProductsSize();
if (model.Dynamic_ProductsSize.Count > 0)
{
foreach (var item in model.Dynamic_ProductsSize)
{
_size.SizeId = item;
_sizes.Add(_size);
}
}
model.ProductsSize = _sizes.ToList();
I need to know why it only takes the last item and what is the solution for this case
You only have one ProductsSize object:
var _size = new ProductsSize();
And you keep modifying that same object. All references to that object, including any list elements it's been added to, get updated when you modify that one object.
Instead, create your new object in the loop:
foreach (var item in model.Dynamic_ProductsSize)
{
var _size = new ProductsSize();
_size.SizeId = item;
_sizes.Add(_size);
}
That way each element in the list is a new object instead of the same object added multiple times.
Side note, you have a few things in the code which aren't necessary. Checking the length before the loop, for example, as well as converting a list to a list at the end.
In fact, I imagine all of the code shown can be shortened to simply this:
model.ProductsSize = model.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p }).ToList();
In which case you're also just converting one model property to another model property. Why not put this logic in the model itself and skip the whole thing?
public IEnumerable<ProductsSize> ProductsSize
{
get { return this.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p });
}
Unless there's a particular reason you want the same data twice in two different properties that isn't clear from this code, having one set of data and just different views/calculations/etc. of that data is often preferred.
Create a new object before adding it to the list. You can use the object initializer syntax to keep it concise:
if (model.Dynamic_ProductsSize.Count > 0)
{
foreach (var item in model.Dynamic_ProductsSize)
{
_sizes.Add(new ProductsSize(){SizeId = item});
}
}
query is like this:-
labRequestItem.LabTest.Select(p=>p.LabTestICDCodes= labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray());
Now the issue is that LabTestICDCodes is not updating with the new list value returning from select statement
I have tested in the Linqpad, following shall work, but please note:
finalResult would be List of type of LabTestICDCodes (which is again IEnumerable itself) with new / modified values, as that's the only column projected. You have to project the whole object you want as a result, values will modify as expected
var finalResult =
labRequestItem.LabTest.Select(p=>p.LabTestICDCodes= labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray()).ToList();
I found only way to solve this problem by doing following step:-
1.Get the value in local variable
var icdList = labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray();
Now assign the value by usinf foreach loop.
foreach (var test in labRequestItem.LabTest)
{
test.LabTestICDCodes = icdList;
}
In Last step I have to use foreach loop, if any other solution then
please reply otherwise I will use the same as it mentioned above.
I need to access items from a list which is i am accessing with the following code
foreach (var reportval in reportresponse)
{
foreach (var valitem in reportval.Comparison)
{
var responsemodel = new ReportResponseModel();
responsemodel.StudentVariable = valitem.StudentVariable;
responsemodel.Lighter = valitem.Lighter;
responsemodel.Matched = valitem.Matched;
responsemodel.Stronger = valitem.Stronger;
reportResponseModel.Add(responsemodel);
}
};
I tried the following code to exit the loop without retiterting the first loop. But its not working.
if (reportresponse.Count == reportResponseModel.Count) { break; };
also i tried the following way to access the inner list from the first loop but its not accessible here
foreach (var reportval in reportresponse.Comparison)
Can someone please help on this?
Did you try like this
foreach (var reportval in reportresponse.Comparison)
{
// var responsemodel = new ReportResponseModel();
responsemodel.StudentVariable = valitem.StudentVariable;
responsemodel.Lighter = reportval .Lighter;
responsemodel.Matched = reportval .Matched;
responsemodel.Stronger = reportval .Stronger;
//reportResponseModel.Add(responsemodel);
}
};
Have you tried Linq's SelectMany?
You can do something like
var reportResponseModel = reportresponse.SelectMany(r => r.Comparison, (r, c) =>
new ReportResponseModel
{
StudentVariable = c.StudentVariable,
Lighter = c.Lighter,
Matched = c.Matched,
Stronger = c.Stronger
});
Then you can apply additional filtering like with .Where or .Take to have only needed count of items.
I updated the code with the following changes.
if (reportresponse.Count == reportResponseModel.Count)
{ return reportResponseModel; };
after
reportResponseModel.Add(responsemodel);
Thanks #Stephen Muecke !!
Working on an old application I see this code:, It is using DataTable, DataRow stuff.
foreach (string networkIdToCreate in networkIdsToCreate)
{
HTExtractSchema.HTProviderMedicalGroupContractRow rHTProviderMedicalGroupContract = tblHTProviderMedicalGroupContract.NewHTProviderMedicalGroupContractRow();
rHTProviderMedicalGroupContract.ItemArray = rHTProviderMedicalGroupContractDefaults.ItemArray;
rHTProviderMedicalGroupContract.NetworkId = networkIdToCreate;
rHTProviderMedicalGroupContract.Business = "470";
tblHTProviderMedicalGroupContract.Rows.Add(rHTProviderMedicalGroupContract);
}
So it creates the new row, puts some values in there and adds it to the DataTable.
Now I want to modify it to create two rows instead of one row, all values the same except for "Business" field, it is one line before the last in the code above.
So I did that like this:
foreach (string networkIdToCreate in networkIdsToCreate)
{
HTExtractSchema.HTProviderMedicalGroupContractRow rHTProviderMedicalGroupContract = tblHTProviderMedicalGroupContract.NewHTProviderMedicalGroupContractRow();
rHTProviderMedicalGroupContract.ItemArray = rHTProviderMedicalGroupContractDefaults.ItemArray;
rHTProviderMedicalGroupContract.NetworkId = networkIdToCreate;
rHTProviderMedicalGroupContract.Business = "470";
tblHTProviderMedicalGroupContract.Rows.Add(rHTProviderMedicalGroupContract);
HTExtractSchema.HTProviderMedicalGroupContractRow rHTProviderMedicalGroupContract2 = tblHTProviderMedicalGroupContract.NewHTProviderMedicalGroupContractRow();
rHTProviderMedicalGroupContract2.ItemArray = rHTProviderMedicalGroupContractDefaults.ItemArray;
rHTProviderMedicalGroupContract2.NetworkId = networkIdToCreate;
rHTProviderMedicalGroupContract2.Business = "475";
tblHTProviderMedicalGroupContract.Rows.Add(rHTProviderMedicalGroupContract2);
}
But I was wondering if there is a better way other than this copy paste? so if someone saw the code won't laugh at me :D
Just add this internal loop
foreach(var business in new[] {"470", "475"})
{
...
rHTProviderMedicalGroupContract.Business = business ;
...
}
EDIT
Or you can use a method
private void CreatRow(
string networkIdToCreate,
string business)
{
HTExtractSchema.HTProviderMedicalGroupContractRow rHTProviderMedicalGroupContract =
tblHTProviderMedicalGroupContract.NewHTProviderMedicalGroupContractRow();
rHTProviderMedicalGroupContract.ItemArray =
rHTProviderMedicalGroupContractDefaults.ItemArray;
rHTProviderMedicalGroupContract.NetworkId = networkIdToCreate;
rHTProviderMedicalGroupContract.Business = business;
tblHTProviderMedicalGroupContract.Rows.Add(rHTProviderMedicalGroupContract);
}
and use it like this
foreach (string networkIdToCreate in networkIdsToCreate)
{
CreatRow(networkIdToCreate, "470");
CreatRow(networkIdToCreate, "475");
if(networkIdToCreate == "2" || networkIdToCreate == "6")
{
CreateRow(networkIdToCreate, "474");
}
}
Note you may need to pass in tblHTProviderMedicalGroupContract depending on its scope,