List<T>.addrange() not working - c#

I have property :
public List<RequestCheckListDetail> DocumentChecklistMasterList
{
get
{
if (ViewState["DocumentChecklistMasterList"].IsObjectUsable())
_documentChecklistMasterList = (List<RequestCheckListDetail>)ViewState["DocumentChecklistMasterList"];
else
this._documentChecklistMasterList = new List<RequestCheckListDetail>();
return this._documentChecklistMasterList;
}
set { ViewState["DocumentChecklistMasterList"] = value; }
}
I am trying to add data to it using another list. However another list has different entity, so i am running loop over first list like:
List<RequestCheckListDetail> newList = new List<RequestCheckListDetail>();
int i = 0;
foreach (DocumentCheckListMaster item in list)
{
newList.Add(new RequestCheckListDetail
{
Id = i,
CheckListMaster = item
});
i++;
}
this.DocumentChecklistMasterList.AddRange(newList);
even if newList has items in it, DocumentChecklistMasterList always have 0 items.
I have tried following things:
List<RequestCheckListDetail> newList = new List<RequestCheckListDetail>();
int i = 0;
foreach (DocumentCheckListMaster item in list)
{
this.DocumentChecklistMasterList.Add(new RequestCheckListDetail
{
Id = i,
CheckListMaster = item
});
i++;
}
List<RequestCheckListDetail> newList = new List<RequestCheckListDetail>();
int i = 0;
foreach (DocumentCheckListMaster item in list)
{
this.DocumentChecklistMasterList.Insert(i,
new RequestCheckListDetail {
Id = i,
CheckListMaster = item
});
i++;
}
None of these codes are working properly.
I am still not able to add items to DocumentChecklistMasterList
Please help me:
EDIT:
IsObjectUsable() is extension method i have added to check if object is null
public static bool IsObjectUsable(this object checkObject)
{
bool isUsable = true;
if (checkObject == null || checkObject == DBNull.Value)
{
isUsable = false;
}
return isUsable;
}

Related

C#, Newtonsoft, need to get array items not already handled

I have a json array that looks like...
{
"equipment": [{
"date_of_examination": "2022-05-20T14:08:38.072965",
"defect_type": ["DN"],
"eqpt_ref": "AA1",
"eqpt_name": ["2 Leg Chain Sling"],
"eqpt_manufacturer": "Merc",
"eqpt_model": "edes",
"part_no": "A1",
"serial_no": "A1",
"year": "2019",
"swl": "32 tons",
"exam_type": ["6 Months"],
"date_of_last_examination": "2021-11-20T00:00:00",
"date_of_next_examination": "2022-11-20T00:00:00",
"defect": "sling is torn",
"action_required": "replace"
}, {
"date_of_examination": "2022-05-20T14:12:23.997004",
"eqpt_ref": "AA2",
"eqpt_name": ["Other - "],
"eqpt_name_other": "widget",
"eqpt_manufacturer": "merc",
"eqpt_model": "edes",
"part_no": "B1",
"serial_no": "B1",
"year": "2019",
"swl": "32 tons",
"exam_type": ["6 Months"]
}, {
"date_of_examination": "2022-05-20T14:13:24.795136",
"defect_type": ["DF"],
"eqpt_ref": "CC1",
"eqpt_name": ["Endless Round Sling (2.5m)"],
"eqpt_manufacturer": "merc",
"eqpt_model": "edes",
"part_no": "c1",
"serial_no": "c1",
"year": "2019",
"swl": "42 tons",
"exam_type": ["6 Months"],
"defect": "stitching is coming undone",
"danger_value": "6",
"danger_units": ["Weeks"],
"action_required": "needs to be stitched again"
}]
}
I am attempting to loop through the array and filter items as I need, to populate a table later.
The table has three parts.
First, is show all items with a defect_type of "DN". Second is to show all defect_type of "DF", and the last part is to show all the rest (in his case, the one with eqpt_name of AA2)
My original code is...
for (int j = 0; j <= 2; j++)
{
// Note, some table name parts won't have the "Filter..." aspect
// the string below will change depending on which loop we are in.
string[] tableNameParts = "TableStart:equipment:defectNow:Filter:defect_type=DN".Split(':');
string tableNameJson = tableNameParts[1].Replace("»", "");
var jsonRows = IncomingJson[tableNameJson];
if (tableNameParts.Count() > 3)
{
// We probably have a filter set.
if (tableNameParts[3].Replace("»", "").ToLower() == "filter" && tableNameParts.Count() > 4)
{
// These values are not set in stone. It is what values have been set in the JSON, and then matched.
// for example... TableStart:<subform name>:<differentiator>:Filter:<field name>=<field value>
string[] FilterParts = tableNameParts[4].Split('=');
// Get the filter field and value to filter by
if (FilterParts.Count() > 1)
{
string FilterField = FilterParts[0].Replace("»", "");
string FilterValue = FilterParts[1].Replace("»", "");
JArray filteredArray = new JArray();
if (jsonRows[0].GetType() == typeof(JObject))
{
//int loopCount = 0;
foreach (JObject arrayObject in jsonRows) // Each group can have a set of arrays. (each record has multiple sub records)
//for (int i = 0; i < jsonRows.Count(); i++)
{
//JObject arrayObject = jsonRows[i];
foreach (var objectItem in arrayObject)
{
string objectItemValue = string.Empty;
if (objectItem.Value.GetType() == typeof(JArray))
{
foreach (var item in objectItem.Value)
{
objectItemValue += item;
}
}
else
{
objectItemValue = (string)objectItem.Value;
}
if (objectItem.Key == FilterField && objectItemValue == FilterValue)
{
// We need to save the item.
filteredArray.Add(arrayObject);
testArray.Add(arrayObject);
//arrayObject["filtered"] = true;
//IncomingJson[tableNameJson][loopCount]["filtered"] = true;
}
}
//loopCount++;
}
}
else
{
foreach (JArray arrayGroup in jsonRows) // The array group (e.g. fault_record_subform)
{
// We are looking through the json array, to find any rows that match our filter key and filter value.
// We will then add that into our jsonRows
//int loopCount = 0;
foreach (JObject arrayObject in arrayGroup) // Each group can have a set of arrays. (each record has multiple sub records)
{
foreach (var objectItem in arrayObject)
{
string objectItemValue = string.Empty;
if (objectItem.Value.GetType() == typeof(JArray))
{
foreach (var item in objectItem.Value)
{
objectItemValue += item;
}
}
else
{
objectItemValue = (string)objectItem.Value;
}
if (objectItem.Key == FilterField && objectItemValue == FilterValue)
{
// We need to save the item.
filteredArray.Add(arrayObject);
testArray.Add(arrayObject);
//arrayObject["filtered"] = true;
//IncomingJson[tableNameJson][loopCount]["filtered"] = true;
}
}
}
//loopCount++;
}
}
//filteredArray.CopyTo(testArray, 0);
jsonRows = filteredArray; // limit the jsonRows to the filtered set (overwrite the jsonRows)
}
}
}
else
{
// This is not a filter set
JArray singleArray = new JArray();
foreach(var arraySet in jsonRows)
{
if (!testArray.Intersect(arraySet).Any())
{
if (arraySet.GetType() == typeof(JObject))
{
singleArray.Add(arraySet);
}
else
{
foreach (JObject arrayObject in arraySet)
{
singleArray.Add(arrayObject);
}
}
}
}
jsonRows = singleArray;
}
}
By the time it gets to the "this is not a filter set" (which should be the third iteration of the loop), I need to be able to ignore the other filtered items, but as you might see, I have attempted to mark an item as filtered (then filter out). I have also tried to add the filtered items to an alternative array and use that to filter out. All to no avail.
How do I make it so that the "this is not a filter set" rows can ignore the rows already filtered?
=========== EDIT ==============
After reviewing the link from dbc to the fiddler (I don't have an account on there, and don't know how to link to my changes), I have it running in the fiddler with the code below.
JObject json = JObject.Parse(GetJson());
string[] tableNames = {"TableStart:equipment:defectNow:Filter:defect_type=DN","TableStart:equipment:defectFuture:Filter:defect_type=DF","TableStart:equipment:defectNone"};
for (int j = 0; j <= 2; j++)
{
// Note, some table name parts won't have the "Filter..." aspect
// the string below will change depending on which loop we are in.
string[] tableNameParts = tableNames[j].Split(':');
string tableNameJson = tableNameParts[1].Replace("»", "");
var jsonRows = json[tableNameJson];
if (tableNameParts.Count() > 3)
{
// We probably have a filter set.
if (tableNameParts[3].Replace("»", "").ToLower() == "filter" && tableNameParts.Count() > 4)
{
// These values are not set in stone. It is what values have been set in the JSON, and then matched.
// for example... TableStart:<subform name>:<differentiator>:Filter:<field name>=<field value>
string[] FilterParts = tableNameParts[4].Split('=');
// Get the filter field and value to filter by
if (FilterParts.Count() > 1)
{
string FilterField = FilterParts[0].Replace("»", "");
string FilterValue = FilterParts[1].Replace("»", "");
JArray filteredArray = new JArray();
if (jsonRows[0].GetType() == typeof(JObject))
{
//int loopCount = 0;
foreach (JObject arrayObject in jsonRows) // Each group can have a set of arrays. (each record has multiple sub records)
//for (int i = 0; i < jsonRows.Count(); i++)
{
//JObject arrayObject = jsonRows[i];
foreach (var objectItem in arrayObject)
{
string objectItemValue = string.Empty;
if (objectItem.Value.GetType() == typeof(JArray))
{
foreach (var item in objectItem.Value)
{
objectItemValue += item;
}
}
else
{
objectItemValue = (string)objectItem.Value;
}
if (objectItem.Key == FilterField && objectItemValue == FilterValue)
{
// We need to save the item.
filteredArray.Add(arrayObject);
//testArray.Add(arrayObject);
//arrayObject["filtered"] = true;
//IncomingJson[tableNameJson][loopCount]["filtered"] = true;
}
}
//loopCount++;
}
}
else
{
foreach (JArray arrayGroup in jsonRows) // The array group (e.g. fault_record_subform)
{
// We are looking through the json array, to find any rows that match our filter key and filter value.
// We will then add that into our jsonRows
//int loopCount = 0;
foreach (JObject arrayObject in arrayGroup) // Each group can have a set of arrays. (each record has multiple sub records)
{
foreach (var objectItem in arrayObject)
{
string objectItemValue = string.Empty;
if (objectItem.Value.GetType() == typeof(JArray))
{
foreach (var item in objectItem.Value)
{
objectItemValue += item;
}
}
else
{
objectItemValue = (string)objectItem.Value;
}
if (objectItem.Key == FilterField && objectItemValue == FilterValue)
{
// We need to save the item.
filteredArray.Add(arrayObject);
//testArray.Add(arrayObject);
//arrayObject["filtered"] = true;
//IncomingJson[tableNameJson][loopCount]["filtered"] = true;
}
}
}
//loopCount++;
}
}
//filteredArray.CopyTo(testArray, 0);
jsonRows = filteredArray; // limit the jsonRows to the filtered set (overwrite the jsonRows)
}
}
}
else
{
// This is not a filter set
JArray singleArray = new JArray();
foreach(var arraySet in jsonRows)
{
//if (!testArray.Intersect(arraySet).Any())
{
if (arraySet.GetType() == typeof(JObject))
{
singleArray.Add(arraySet);
}
else
{
foreach (JObject arrayObject in arraySet)
{
singleArray.Add(arrayObject);
}
}
}
}
jsonRows = singleArray;
}
}
What I need ultimately (the jsonRows will be used elsewhere in my code within the loop) is that the third set will have items not found in the first 2 sets.
After a bit of further experimentation, using dotnetfiddle as introduced to me by #dbc (thank you), I have created a List and added each arrayObject into the list during the filtering stages.
I then during the unfiltered stage check if my arraySet is contained in the List, and if not, then add that item to the remaining jsonRows, thereby giving me the balance of the original list.
As can be seen here...
https://dotnetfiddle.net/ot35Z2

how to pass viewmodel in to view

I have a viewmodel called "PlanObjectsViewModel". I need to add results inside of my while loop to an instance of PlanObjectsViewModel.I tried following approach..Is that wrong?? I'm getting an exception called;
The model item passed into the dictionary is of type 'MvcApp.ViewModel.PlanObjectsViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MvcApp.ViewModel.PlanObjectsViewModel]'.
var model2 = model1.GroupBy(t => t.Type).Select(g => new PlanBaseTypedObjects
{
Id = g.Key,
ObjectDetails = g
});
int Type1 = 0;
int Type2 = 0;
double? temp = 0;
foreach (var item in model2)
{
if(item.Id==1)
Type1 = item.ObjectDetails.Count();
if (item.Id == 2)
Type2 = item.ObjectDetails.Count();
}
Random rand = new Random();
var final = new PlanObjectsViewModel(); // want to add data to this view model
while (budget > temp)
{
if (Type1 != 0) {
int randi = rand.Next(0, Type1);
foreach (var item in model2)
{
if (item.Id == 1) { foreach (var x in item.ObjectDetails) {
if (x.Id == randi)
final.Id = x.Id;// i don't know,whether this is a correct way to
//add data row to the model
temp=temp+x.Price;
}
}
}
}
if (Type2 != 0)
{
int randi = rand.Next(0, Type2);
foreach (var item in model2)
{
if (item.Id == 2)
{
foreach (var x in item.ObjectDetails)
{
if (x.Id == randi)
final.Id = x.Id;
temp = temp + x.Price;
}
}
}
}
}
return View(model1);
In my view i have;
#model IEnumerable<MvcApp.ViewModel.PlanObjectsViewModel>
can anyone explain why is that?? if i'm doing it it a wrong way,what is the best approach??Thank you.
You're expecting a collection but you pass in an individual item to the view instead.
MvcApp.ViewModel.PlanObjectsViewModel = object
System.Collections.Generic.IEnumerable[MvcApp.ViewModel.PlanObjectsViewModel] = collection of objects
Change this
#model IEnumerable<MvcApp.ViewModel.PlanObjectsViewModel>
to
#model MvcApp.ViewModel.PlanObjectsViewModel

EF: saveChanges succeed, but changes reflect in DB only when edditing existing reference member

I'm using EF.
I have a Parent entity named MamConfiguration_V1
it has a EntityCollection of MamConfigurationToBrowser_V1
my context is mMaMDBEntities.
I'm trying to add a new MamConfigurationToBrowser_V1 to an existing MamConfiguration_V1
I get no errors, but no record is added to the DB.
When I update an existing reference member, changes are reflected in the DB.
What am I doing wrong?
public MamConfiguration_V1 Save(MamConfiguration_V1 item)
{
try
{
var itemFromDB = mMaMDBEntities.MamConfiguration_V1.SingleOrDefault(a=> a.ConfigurationId == item.ConfigurationId);
if (itemFromDB != null)
{
UpdateEfBrowsers(itemFromDB, item);
mMaMDBEntities.SaveChanges();
return item;
}
else
{
throw new KeyNotFoundException(string.Format("configurationId = {0} wasn't found in the DB", item.ConfigurationId));
}
}
private void UpdateEfBrowsers(MamConfiguration_V1 itemFromDb, MamConfiguration_V1 itemFromUi)
{
foreach (var item in itemFromDb.MamConfigurationToBrowser_V1.ToList())
{
if (itemFromUi.MamConfigurationToBrowser_V1.All(b => b.BrowserVersionId != item.BrowserVersionId))
{
mMaMDBEntities.MamConfigurationToBrowser_V1.DeleteObject(item);
}
}
for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++)
{
var element = itemFromUi.MamConfigurationToBrowser_V1.ElementAt(i);
var item =
itemFromDb.MamConfigurationToBrowser_V1.SingleOrDefault(b => b.BrowserVersionId == element.BrowserVersionId);
if (item != null)
{
// copy properties from element to item
}
//add new
else
{
//element.Browser = mMaMDBEntities.Browsers.Single(browserItem =>
// browserItem.BrowserID == element.BrowserID);
//element.MamConfigurationId = itemFromDb.ConfigurationId;
element.MamConfiguration_V1 = null;
mMaMDBEntities.MamConfigurationToBrowser_V1.AddObject(element);
itemFromDb.MamConfigurationToBrowser_V1.Add(element);
}
}
}
for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++)
{
...
mMaMDBEntities.MamConfigurationToBrowser_V1.AddObject(element);
itemFromDb.MamConfigurationToBrowser_V1.Add(element);
}
The problem was that the AddObject or Add
remove an item from itemFromUi.MamConfigurationToBrowser_V1.Count
and thus decreases count.
I don't know why.
I have replaced with foreach
You need to write
*databasename*.SaveChanges()
After you have added to the database. Otherwise it will not save it

Add list of objects to List<List<Objects>> if not contain

I have List<List<Vertex>> , Vertex has a property id. I need to add List<Vertex>> into this list, but not duplicate lists.
public void AddComponent(List<Vertex> list)
{
List<List<Vertex>> components = new List<List<Vertex>>;
//I need something like
if (!components.Contain(list)) components.Add(list);
}
You can use SequenceEqual - (this means the order must also be the same):
if (!components.Any(l => l.SequenceEqual(list)))
components.Add(list);
You could do something like:
public void AddComponent(List<Vertex> list)
{
var isInList = components.Any(componentList =>
{
// Check for equality
if (componentList.Count != list.Count)
return false;
for (var i = 0; i < componentList.Count; i++) {
if (componentList[i] != list[i])
return false;
}
return true;
});
if (!isInList)
components.Add(list);
}

Comparing on one element of on object in a list?

I have a custom class containing 2 public variables: 1 is a string and 1 is an integer. I then make a list of this class, in the list I need the string of the class to be unique, if the string already exists in the list I don't want to add it again but I do want to combine the corresponding integers. here is an example of the custom class and list.
public class myItems
{
public string itemName;
public int count;
}
List<myItems> items = new List<myItems>();
myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
items.Add(e);
myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
items.Add(e1);
myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
items.Add(e5);
So for the final list i want to it contain: pencil 7, eraser 4. I have been using the contains function on the list to check if it already exists but it only returns true if both the string and integer are the same.
Is there a way to only match on the string?
Another way to do it would be to use LINQ:
public class myItems
{
public string itemName;
public int count;
}
List<myItems> items = new List<myItems>();
myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
Add(items, e);
myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
Add(items, e1);
myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
Add(items, e5);
public void Add(List<myItems> list, myItems newItem)
{
var item = list.SingleOrDefault(x => x.symbol == newItem.symbol);
if(item != null)
{
item.count += newItem.count;
}
else
{
list.Add(newItem);
}
}
A dictionary might be well suited for this problem:
readonly Dictionary<string, int> _dict = new Dictionary<string, int>();
void InsertOrUpdate(string name, int count)
{
int previousCount = 0;
// item already in dictionary?
if (_dict.TryGetValue(name, out previousCount))
{
// add to count
count += previousCount;
}
_dict[name] = count;
}
void Main()
{
InsertOrUpdate("pencil", 3);
InsertOrUpdate("eraser", 3);
InsertOrUpdate("pencil", 4);
// print them
foreach (var item in _dict)
Console.WriteLine(item.Key + " " + item.Value);
}
You could add an Equals method to your class, or use LINQ with something like
items.Where(i => i.itemName == "pencil")
However, if all you are doing is keeping track of how many 'items' you have, would a Dictionary that maps itemNames to counts solve your problem easier? Then you would be able to do things like
// Assuming you want to add a new 'pencil' with a count of 3
int oldCount = 0;
items.TryGetValue("pencil", out oldCount);
items["pencil"] = oldCount + 3;
Usually see something like this called a Bag
Sure, write a custom Equals method
public override bool Equals(object o)
{
MyItems mi = o as MyItems;
if (mi == null)
return false;
if (itemName == null)
return mi.itemName == null;
return itemName.Equals(mi.itemName);
}
public override int HashCode()
{
return (itemName ?? string.Empty).HashCode();
}
That being said, you really should be using a dictionary/hash table instead, since a dictionary provides much faster lookup when you know what you want. A List implementation will cause the list to be searched in its entirety every time you want to add a MyItem to the list.
when you check if it contains and it returs true than you get the index and add the number to it. use that logic. it will work.

Categories

Resources