SessionResponseList objClientSessionResponseList = new SessionResponseList();
objClientSessionResponseList.QId = Convert.ToInt32(Session["QuestionNumber"]);
objClientSessionResponseList.QAnswer = Session["CurrentAnswer"].ToString();
objSessionResponseList = (List<SessionResponseList>)Session["Answers"];
if (objSessionResponseList.Where(x=>x.QId == objClientSessionResponseList.QId && x.QAnswer==objClientSessionResponseList.QAnswer).Count()>0)
{
objSessionResponseList.Remove(objClientSessionResponseList);
Session["Answers"] = objSessionResponseList;
}
// objSessionResponseList.Remove(objClientSessionResponseList);
//This isn't working tried everything the values are exact duplicate
Please help.
public class SessionResponseList{
public int QId { get; set; }
public string QAnswer { get; set; }
}
Instead of creating a new instance you should try getting the instance from the List using FirrstOrDefault and if that is found then remove that instance from the list, currently you are creating a new object and you are trying to remove that from the list.
var itemToBeRemoved = objSessionResponseList
.FirstOrDefault(x=>
x.QId == Convert.ToInt32(Session["QuestionNumber"]) &&
x.QAnswer == Session["CurrentAnswer"].ToString();
if(itemToBeRemoved != null) //means item is found in the list
objSessionResponseList.Remove(itemToBeRemoved)
Related
I have documents that are based on others, through recursion, I find documents that refer to what they are based on, the problem is that they are all duplicated into one, it does not work correctly
not the correct variant
I want to get this
In the code, the main thing that I transfer is the Type of the document and the List of child elements
public async Task<List<DocumentTreeItem>> FillRecursionTree(Guid documentId, string documentPresentationName, List<DocumentTreeItem> treeItems, Type documentType)
{
await FillRecursionTree(documentId, documentPresentationName, treeItems, documentType);
return treeItems;
async Task FillRecursionTree(Guid childrenId, string childrenIdDocumentPresentationName, List<DocumentTreeItem> childrenIdTreeItems, Type childrenIdDocumentType)
{
var currentNode = new DocumentTreeItem(documentPresentationName, childrenIdDocumentType, childrenIdTreeItems)
{
Id = childrenId,
DocumentPresentationName = childrenIdDocumentPresentationName,
TypeDocument = childrenIdDocumentType
};
childrenIdTreeItems.Add(currentNode);
var customerInvoices = await GetBaseCustomerInvoiceDocuments(childrenId);
foreach (var customerInvoice in customerInvoices)
{
childrenIdDocumentType = customerInvoice.GetType();
await FillRecursionTree(customerInvoice.Id, customerInvoice.DocumentPresentationName, **currentNode.Childrens,** childrenIdDocumentType);
}
}
}
if i think correctly i need to add elements to the root element but how do i do it so i don't get then all the elements again if they don't fit
currentNode.Childrens <-
How can I pass from the main document only the required array of child elements, and not all at once, where everything falls.
Maybe I'm wrong and the problem is in the second one.
This is the type in which I keep everything, there is a children's letter in which all the documents made on its basis are recorded.
public Guid Id { get; set; }
public string? DocumentPresentationName { get; set; }
public Type TypeDocument { get; set; }
public List<DocumentTreeItem> Childrens { get; set; } = new List<DocumentTreeItem>();
public DocumentTreeItem(string documentPresentationName, Type typeDocument, List<DocumentTreeItem> children = null)
{
DocumentPresentationName = documentPresentationName;
TypeDocument = typeDocument;
if (children != null)
Children.AddRange(children);
}
public List<DocumentTreeItem> Children
{
get
{
return Childrens;
}
}
I passed the entire array of elements of the root, and did not create a new one
var currentNode = new DocumentTreeItem(documentPresentationName, childrenIdDocumentType, **new List<DocumentTreeItem>()**)
{
Id = childrenId,
DocumentPresentationName = childrenIdDocumentPresentationName,
TypeDocument = childrenIdDocumentType
};
public class PayRateDaysModel
{
public string day_name { get; set; }
public List<RateList> multiplier { get; set; }
}
public class RateList
{
public double start_after { get; set; }
public double rate_multiplier { get; set; }
}
daysModel is a List of type PayRateDaysModel. When I'm trying to update multiplier in current object of daysModel list i.e. dayExists, then its updating multiplier in all the elements of daysModel list. I want to update only in current item.
Below is my code :
var dayExists = daysModel.Where(x => x.day_name == day_name).FirstOrDefault();
if(dayExists==null)
{
PayRateDaysModel days = new PayRateDaysModel();
days.day_name = day_name;
days.multiplier = rate_list;
daysModel.Add(days);
}
else
{
//update
dayExists.day_name = "abc";
dayExists.multiplier.FirstOrDefault().rate_multiplier = 1;
}
Based on what you have shown to us I would think that you are creating the rate_list somewhere above like rate_list = new RateList(…) and you are setting this to all of your days in days.multiplier = rate_list;. Since you did not recreate that rate_list for every element, any time you change it in one of your dayExists you will change it for all the others as well. So you should do something like this days.multiplier = new RateList(…);
Check this link : Updating child items in List updates all Items in C#
I don't see any reason for it not to work. Are you sure you are testing it in right way?
I think it will be better to improve the code and test for null value :
var dayExists = daysModel.Where(x => x.day_name == day_name).FirstOrDefault();
if(dayExists==null)
{
PayRateDaysModel days = new PayRateDaysModel();
days.day_name = day_name;
days.multiplier = rate_list;
daysModel.Add(days);
}
else
{
//update
dayExists.day_name = "abc";
var firstMultiplier= dayExists.multiplier.FirstOrDefault();
if( firstMultiplier!=null)
{
firstMultiplier.rate_multiplier = 1;
}
}
I have an sql query that provides me my data where I sometimes have lines that should be clustered (the data is aligned with an order by). The data is grouped by the field CAPName. Going through those rows line by line, I need to decide whether a new list should be initiated (content of CAPName differs to previous itteration), or whether the (already) initated list (from the previous iteration) should be added, too.
My pain lays with the location of the declaration of the relatedCapabilitySystem list.
I wanted to declare it within the if statement (Because, as I stated I need to decide whether the list from the previous iteration should be added too, or whether it should start a new list), but I can't as the compiler throws an exception, as the RLCapSys.Add(rCs); is non-existing in this content (which is only theoretically true). I understand why the compiler throws this exception. But if I declare the list on a "higher" level, than I always have a new list, which I don't want in the case that the item should be added to the list defined in the iteration(s) (1 or more) before
So what I want to achieve is, generate the list RLCapSys and add to it, in case the previous iteration contains the same CAPName (for clustering), otherwise create a new list.
SqlCommand cmdDetail = new SqlCommand(SQL_SubSytemsToCapability, DBConDetail);
SqlDataReader rdrDetail = cmdDetail.ExecuteReader();
List<relatedCapility> RLCaps = new List<relatedCapility>();
string lastCapShown = null;
while (rdrDetail.Read())
{
List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>();
if (lastCapShown != rdrDetail["CAPName"].ToString())
{
//List<relatedCapabilitySystem> RLCapSys2 = new List<relatedCapabilitySystem>();
relatedCapility rC = new relatedCapility
{
Capability = rdrDetail["CAPName"].ToString(),
systemsRelated = RLCapSys,
};
RLCaps.Add(rC);
}
relatedCapabilitySystem rCs = new relatedCapabilitySystem
{
system = rdrDetail["name"].ToString(),
start = rdrDetail["SysStart"].ToString(),
end = rdrDetail["SysEnd"].ToString(),
};
RLCapSys.Add(rCs);
// method to compare the last related Capability shown create a new related Capabilty entry or add to the existing releated Capabilty related system list
lastCapShown = rdrDetail["CAPName"].ToString();
}
DBConDetail.Close();
and for reason of completness (but I think it is not needed here):
internal class CapabilitiesC
{
public List<Capability>Capabilities{ get;set;}
}
public class Capability
{
public string name { get; internal set; }
public string tower { get; internal set; }
public string color { get; internal set; }
public List<relatedCapility> related { get; set; }
}
public class relatedCapility
{
public string Capability { get; set; }
public List<relatedCapabilitySystem> systemsRelated { get; set; }
}
public class relatedCapabilitySystem
{
public string system { get; set; }
public string start { get; set; }
public string end { get; set; }
}
The purpose of your code is to take the input data and group it by capability. However, that is not immediately obvious. You can change your code to use LINQ so it becomes easier to understand and in the process solving your problem.
First you need a type to represent a record in your database. For lack of better name I will use Record:
class Record
{
public string System { get; set; }
public string Start { get; set; }
public string End { get; set; }
public string Capabilty { get; set; }
}
You can then create an iterator block to return all the records from the database (using an OR mapper like Entity Framework avoids most of this code and you can even shift some of the work from your computer to the database server):
IEnumerable<Record> GetRecords()
{
// Code to create connection and command (preferably in a using statement)
SqlDataReader rdrDetail = cmdDetail.ExecuteReader();
while (rdrDetail.Read())
{
yield return new Record {
System = rdrDetail["name"].ToString(),
Start = rdrDetail["SysStart"].ToString(),
End = rdrDetail["SysEnd"].ToString(),
Capability = rdrDetail["CAPName"].ToString()
};
}
// Close connection (proper using statement will do this)
}
Finally, you can use LINQ to perform the grouping:
var RLCaps = GetRecords()
.GroupBy(
record => record.Capability,
(capability, records) => new relatedCapility
{
Capability = capability ,
systemsRelated = records
.Select(record => new relatedCapabilitySystem
{
system = record.System,
start = record.Start,
end = record.End
})
.ToList()
})
.ToList();
Why not just assign it as NULL. The pattern would be
List<> myList = null;
if(condition)
{
myList = new List<>();
}
else
{
myList = previousList;
}
myList.Add();
previousList = myList;
I've got it working now. Thx everyone for your help. #martin, thx for your solution, you have put quite some effort into this, but that would have required for me to completely re-write my code. I am sure your approach would work and will be my next approach should I have a similar problem again.
It was a combination of the other answers that helped me figure it out. Let me show you what I ended up with:
SqlCommand cmdDetail = new SqlCommand(SQL_SubSytemsToCapability, DBConDetail);
SqlDataReader rdrDetail = cmdDetail.ExecuteReader();
List<relatedCapility> RLCaps = new List<relatedCapility>();
List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>();
string lastCapShown = null;
while (rdrDetail.Read())
{
if (lastCapShown != rdrDetail["CAPName"].ToString())
{
RLCapSys = relatedCapabilitySystemList();
relatedCapility rC = new relatedCapility
{
Capability = rdrDetail["CAPName"].ToString(),
systemsRelated = RLCapSys,
};
RLCaps.Add(rC);
}
relatedCapabilitySystem rCs = new relatedCapabilitySystem
{
system = rdrDetail["name"].ToString(),
start = rdrDetail["SysStart"].ToString(),
end = rdrDetail["SysEnd"].ToString(),
};
RLCapSys.Add(rCs);
// method to compare the last related Capability shown create a new related Capabilty entry or add to the existing releated Capabilty related system list
lastCapShown = rdrDetail["CAPName"].ToString();
}
DBConDetail.Close();
So that's the section already shown bevor including my changes. Plus I added this:
private List<relatedCapabilitySystem> relatedCapabilitySystemList()
{
List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>();
return RLCapSys;
}
Now I have new list reference everytime the CapName changes that is then added to the "higher" list. Before I had the issue of the very same list repeatedly assigned rather than a fresh one started. So thx again for your effort.
I have list following:
public class matrix
{
public string Row { get; set; }
public string Column { get; set; }
public int Value { get; set; }
}
So, in my main method the two list is following which have different values
List<matrix> matrixList1 = new List<matrix>();
List<matrix> matrixList2 = new List<matrix>();
Now I have tried so many times to find the most unmatched data from that two list where the values of the three properties ie. Row, Column and Value will be different using LINQ. Actually i am looking for the non-matched values from that two list 'matrixlist1' and 'matrixlist2'
where (matrixlist1.Row != matrixlist2.Row && matrixlist1.Column != matrixlist2.Column && matrixlist1.Value != matrixList2.value). Could you please help me regarding this? Thank you in advance.
Something like this:
var uniqueItems = matrixList1.Where(l1 => !matrixList2.Any(l2 => l1.Row == l2.Row && l1.Column == l2.Column && l1.Value == l2.Value))
I have a WizardInfo class which as several TLists as properties, this then populates as the user goes through the wizard on the last screen I query the Tlists and make them into Lists and private fields
I then create Lists of DefaultItems from these lists. This is my own class and as name and Id as its property.
He is some code
public class DefaultItem
{
public int ID {get;set;}
public string Name {get;set;}
}
private List<DefaultItem> _defaultList = null;
_defaultList = new List<DefaultItem>();
defaultValue = PopulateDefaultList(_asmgps, defaultList);
private int PopulateDefaultList(
List<ASGMP> asmgps,
ref List<DefaultItem> defaultList)
{
int isdefault = -1;
foreach (ASGMP asgmp in asgmps)
{
if (asgmp.IsChecked)
{
if (asgmp.IsDefault)
{
isdefault = asgmp.ID;
}
DefaultItem defaultItem = new DefaultItem();
defaultItem.ID = asgmp.ID;
defaultItem.Name = GetMPTName(asgmp.ID);
defaultList.Add(defaultItem);
}
}
return isdefault;
}
private string GetMPTName(int ID)
{
try
{
SGMP sgmp = DataRepository.SGMPProvider.GetByASGMPID(ID)
if (serviceGroupMailPresentation != null)
{
MPT mpt DataRepository.MPTProvider.GetByMPTID(SGMP.MPTID);
if (mailPresentationType != null)
{
return mpt.Name;
}
}
return string.Empty;
}
catch (Exception ex)
{
WindowsEventLog.Write(ex);
throw;
}
}
The problem i am having is when i remove a item from the defaultList it affects asgmp.
I have found the answer. When I get the mpt name I get asgmp from the database this is where Codesmith does a strange thing and connects the usage of the List and the DefaultList. By querying the original List instead of going to the database it now works fine.
It is being removed because List<T> is derived from object, and is a Reference type. Reference types are passed by reference, i.e. when you pass your list, you are passing a pointer to its location in memory. So any changed you make on the copied reference, will also be reflected on the original object.
In order to make a copy you can change this like:
defaultValue = PopulateDefaultList(_asmgps, defaultList);
to this:
defaultValue = PopulateDefaultList(_asmgps.ToList(), defaultList);
This will enumerate the collection as IEnumerable<T> and return is as a list. This will effectivlly create a copy.
erm, instead of PopulateDefaultList why not just do,
var defaultList = asgmps
.Where(asgmp => asgmp.IsChecked)
.Select(asgmp => new
{
IsDefault = asgmp.IsDefault,
Item = new DefaultItem
{
ID = asgmp.ID,
Name = GetMPTName(asgmp.ID)
}
}).ToList();
of course, naming a collection defaultList that contains non-defaults seems counter intuitive.
I found out that this is because of ntiers instead of using the database the to get the ID I should of used the in List of T in