Removing Rows in Entity Framework - c#

What I am trying to create is when a user select an item, that item will disappear from the list of items. Some items can be submitted once and once it is submitted, the user not be able to submit the same item again. Submitted items will be logged to the database.
The issue I am having is figuring out what is wrong with my logic here as it is breaking and what can I do to improve this?
using (var db = new myDatabase())
{
var itemLists = db.GetAllItem().ToList();
var userSubmittedItems = db.GetAllUserItem("LoginID").ToList();
if (userSubmittedItems.Count > 0)
{
foreach (var submittedItems in userSubmittedItems)
{
foreach (var item in itemLists)
{
int itemID = item.ItemID;
int userItemID = userSubmittedItems.UserItemID;
if (itemID == userItemID && item.OneTime == true)
{
itemLists.Remove(item);
}
}
}
}

you're only removing the items in your collection itemLists, you are not performing anything in the database it self... for that you should, and imagining that your Entity for the Items is called ItemEntity do this:
using (var db = new myDatabase())
{
var itemLists = db.GetAllItem().ToList();
var userSubmittedItems = db.GetAllUserItem("LoginID").ToList();
if (userSubmittedItems.Count > 0)
{
foreach (var submittedItems in userSubmittedItems)
{
foreach (var item in itemLists)
{
int itemID = item.ItemID;
int userItemID = userSubmittedItems.UserItemID;
if (itemID == userItemID && item.OneTime == true)
{
itemLists.Remove(item);
db.ItemEntity.Remove(item); // mark for delete
}
}
}
db.SaveChanges(); // all marked items, if any, will now
// be committed in a db call
}
more on removing records with EF: Delete a single record from Entity Framework?

Related

Could we apply foreach loop in controller without accessing view?

I have to check/traverse the table data to delete my user from extra entries using foreach loop.
How can I retrieve my table from controller with foreach loop without accessing to any view.
public ActionResult Accept(int id = 0)
{
Proposal_Requests prop_req = db.Proposal_Request.Find(id);
if (prop_req == null)
{
return HttpNotFound();
}
prop_req.Accept_Date = DateTime.Now;
prop_req.Status = "Proposal Accepted";
db.Entry(prop_req).State = EntityState.Modified;
db.SaveChanges();
foreach( var item in Proposal_Requests)
{
if(item.id!= prop_req.id)
{
if(item.std1 == prop_req.std1 || item.std1 = prop_req.std2 || item.std1 == prop_req.std3)
{
item.std1 = " " ;
}
if(item.std2 == prop_req.std1 || item.std2 == prop_req.std2 || item.std2 == prop_req.std3)
{
item.std2 = " " ;
}
if(item.std3 == prop_req.std1 || item.std3 == prop_req.std2 || item.std3 == prop_req.std3)
{
item.std3 = " " ;
}
}
return RedirectToAction("Index", "Proposal_Requests");
}
i want to delete the user id from all the requests when one of its request get accepted or disable all the requests created by that user.
Proposal_Request is the table from which i wanted to remove
Std_Id (student id)
stored in one of its columns.
Proposal_Requests prop_req = db.Proposal_Request.Find(id);
when this id get accepted by the supervisor.
All the students who are enrolled for this proposal get deleted from
the other proposals.
for this I'm using foreach loop so that every row of the table
Proposal_Request get traversed and data matched to delete the student IDs from the other PROPOSALS with the same STD_ID as the accepted on.

Move record from a Table to another using foreach in C#

My code
tbl_Birthday tblB = new tbl_Birthday();
string today = "01/10/2018";
var query = from a in db.tbl_users.ToList() where a.birthday == today select a;
if (query.Count() > 0)
{
foreach (var a in query.ToList())
{
tblB.name = a.name;
tblB.score = a.core;
}
db.tbl_Birthdays.InsertOnSubmit(tblB);
db.SubmitChanges();
}
dataGridView1.DataSource = from a in db.tbl_Birthdays select a;
This return just one record into my DataGridView, but i have more then one record that conform this condition
You need to move the InsertOnSubmit inside the foreach loop. Currently your foreach loop is just setting the name and score properties over and over again, until it exits. Then you call SubmitChanges on a single item:
foreach (var user in db.tbl_users.Where(user => user.birthday == "01/10/2018"))
{
db.tbl_Birthdays.InsertOnSubmit(
new tbl_Birthday{ name = user.name, score = user.score });
}
db.SubmitChanges();

Recursive delete in c#

I have a parent that I want to delete. It looks like this :
-Parent
- Child 1
-Subchild 1
-Subchild 2
When I delete parent, I want to also delete Subchild. This is my code :
public void DeleteMenu(int id)
{
var item = this.db.Menus.Single(x => x.Id == id);
//DELETE FOREIGN KEYS
//MenuLanguageSet
var languages = from listLanguages in this.db.MenuLanguageSet
where listLanguages.idMenu == id
select listLanguages;
foreach (var itemLanguages in languages)
{
this.db.MenuLanguageSet.Remove(itemLanguages);
}
//Accesses
var accesses = from listAccesses in this.db.Accesses
where listAccesses.menuId == id
select listAccesses;
foreach (var itemAccesses in accesses)
{
this.db.Accesses.Remove(itemAccesses);
}
//DELETE CHILD
//Menus
var menusChild = from listmenus in this.db.Menus
where listmenus.parentId == id
select listmenus;
foreach (var child in menusChild)
{
DeleteMenu(child.Id);
}
//delete parent
this.db.Menus.Remove(item);
this.db.SaveChanges();
}
This is not working and I dont know why. I don't know how to make my loop.
Got it !
This is my final code :
public void DeleteMenu(int id)
{
this.RecursiveDeleteMenu(id);
this.db.SaveChanges();
}
public void RecursiveDeleteMenu(int id)
{
var item = this.db.Menus.Single(x => x.Id == id);
//DELETE FOREIGN KEYS
//MenuLanguageSet
var languages = from listLanguages in this.db.MenuLanguageSet
where listLanguages.idMenu == id
select listLanguages;
foreach (var itemLanguages in languages)
{
this.db.MenuLanguageSet.Remove(itemLanguages);
}
//Accesses
var accesses = from listAccesses in this.db.Accesses
where listAccesses.menuId == id
select listAccesses;
foreach (var itemAccesses in accesses)
{
this.db.Accesses.Remove(itemAccesses);
}
//DELETE CHILD
//Menus
var menusChild = from listmenus in this.db.Menus
where listmenus.parentId == id
select listmenus;
foreach (var child in menusChild)
{
RecursiveDeleteMenu(child.Id);
}
//delete parent
this.db.Menus.Remove(item);
}
I've got the error New transaction is not allowed because there are other threads running in the session because this.db.SaveChanges() was in a loop.
Thank you everyone!

Comparing Two Collections data with each other

I have two observable collections. 1. TruckItems 2. TruckItemsComparison. Both are exactly the same.
I load data into the first TruckItems collection from EF6, then 10 seconds later I load data into the second collection TruckItemsComparison. Now the new data that was added in my 2nd collection might have been updated lately from another source and I need to only add the latest data that does not yet exist in my first collection.
I want to check if ANY of the id's from my 2nd collection does not match any of the id's in my first collection and then only add the items that does not match.
CODE:
Here is where I load my data:
private async void LoadTrucks()
{
using (TruckServiceClient service = new TruckServiceClient())
{
var items = await service.GetTrucksAsync();
if (TruckItems.Count == 0)
{
foreach (var item in items)
{
TruckItems.Add(new TruckItems
{
TruckId = item.TruckId,
TruckQuoteId = item.QuoteId,
TruckPhaseId = item.CurrentPhaseId,
TruckChassisManufacturer = item.ChassisManufacturer,
TruckChassisModel = item.ChassisModel,
TruckStatus = item.Status,
TruckJobNumber = item.JobNumbers,
TruckAddedBy = item.AddedBy,
TruckClientName = item.ClientName,
TruckClientSurname = item.ClientSurname,
TruckClientDetail = item.ClientDetail,
TruckCurrentPhase = item.CurrentPhase
});
}
}
foreach (var item in items)
{
TruckItemsComparison.Add(new TruckItems
{
TruckId = item.TruckId,
TruckQuoteId = item.QuoteId,
TruckPhaseId = item.CurrentPhaseId,
TruckChassisManufacturer = item.ChassisManufacturer,
TruckChassisModel = item.ChassisModel,
TruckStatus = item.Status,
TruckJobNumber = item.JobNumbers,
TruckAddedBy = item.AddedBy,
TruckClientName = item.ClientName,
TruckClientSurname = item.ClientSurname,
TruckClientDetail = item.ClientDetail,
TruckCurrentPhase = item.CurrentPhase
});
}
}
}
And here is where I want to compare my two collections:
public void UpdateTrucks()
{
LoadTrucks();
if (TruckItems.Count != 0)
{
var truckItemsId = TruckItems.Where(x => x.TruckId != 0).First().TruckId;
foreach (var item in TruckItemsComparison.Where(x => x.TruckId != truckItemsId))
{
TruckItems.Add(item);
}
}
}
My problem is that it adds the data from both the two collections together, regardless if the id's correspond or not. Clearly my logic here does not work, so can anyone please show me a way of how I can compare the data and only insert id's that do not yet exist in my TruckItems collection. Thanks and please let me know if you need any more information.
You can enumerate through each of the items in your TruckItemsComparison by using Except:
public void UpdateTrucks()
{
LoadTrucks();
if (TruckItems.Count != 0)
{
foreach (var item in TruckItemsComparison.Except(TruckItems))
{
TruckItems.Add(item);
}
}
}
If all you want to do is compare the Ids of your TruckItems then you can implement your own IEqualityComparer:
internal class TruckItemsComparer : IEqualityComparer<TruckItems>
{
#region IEqualityComparer Members
public bool Equals(TruckItems x, TruckItems y)
{
return (((x == null) && (y == null)) ||
((x != null) && (y != null) && x.TruckId == y.TruckId));
}
public int GetHashCode(TruckItems obj)
{
return obj. TruckId.GetHashCode();
}
#endregion
}
And then use like so:
foreach (var item in TruckItemsComparison.Except(TruckItems, new TruckItemsComparer()))

save children along with parent linq to sql

I have two tables Rule and RuleCondition (one -> many).
people can add conditions at any time.
Suppose initially he adds two conditions.
He can comeback and add another condition also can update the conditions that are already added.
I am able to save the updated conditions, but not able to insert the extra condition he added.
Below is my code, and it is failing at
rule.RuleConditions.Add(oRuleCon); -- Entity set was modified during enumaration
If I use the approach
oAngieCtxt.RuleConditions.InsertOnSubmit(oRuleCon);
it is not at all inserting the data.
can somebody advise how to handle?
public ActionResult saveMetricRule(Rule rule)
{
bool IsNew = rule.RuleId == 0;
using (NewAngieDataContext oAngieCtxt = new NewAngieDataContext(new CSConfigurationMgr().GetConnectionString(ConnectionStringKey.Angie)))
{
if (IsNew)
oAngieCtxt.Rules.InsertOnSubmit(rule);
else
{
RuleCondition oRuleCon = null;
foreach (RuleCondition childItem in rule.RuleConditions)
{
if (childItem.RuleConditionId == 0)
{
oRuleCon = new RuleCondition();
oRuleCon.Points = childItem.Points;
oRuleCon.ConditionValue = childItem.ConditionValue;
oRuleCon.ToOperatorId = childItem.ToOperatorId;
oRuleCon.Sort = childItem.Sort;
rule.RuleConditions.Add(oRuleCon);
// oAngieCtxt.RuleConditions.InsertOnSubmit(oRuleCon);
}
else
{
oRuleCon =
oAngieCtxt.RuleConditions
.Where(CON => CON.RuleConditionId == childItem.RuleConditionId)
.FirstOrDefault();
oRuleCon.Points = childItem.Points;
oRuleCon.ConditionValue = childItem.ConditionValue;
oRuleCon.ToOperatorId = childItem.ToOperatorId;
oRuleCon.Sort = childItem.Sort;
}
}
oAngieCtxt.Rules.Attach(rule);
oAngieCtxt.Refresh(RefreshMode.KeepCurrentValues, rule);
}
oAngieCtxt.SubmitChanges();
}
return this.Json(new
{
msg = "Successful save.",
ruleId = rule.RuleId
});
}
You can't add an item to a list that you're enumerating over. Since you're looping over the rule.RuleConditions, you can't add to it inside the foreach loop. Instead, you can add to a temporary list and then add all items from that list to the rule.RuleConditions after the foreach.
var newRuleConditions = new List<RuleCondition>();
foreach (RuleCondition childItem in rule.RuleConditions)
{
if (childItem.RuleConditionId == 0)
{
oRuleCon = new RuleCondition();
oRuleCon.Points = childItem.Points;
oRuleCon.ConditionValue = childItem.ConditionValue;
oRuleCon.ToOperatorId = childItem.ToOperatorId;
oRuleCon.Sort = childItem.Sort;
//add to temporary list
newRuleConditions.Add(oRuleCon);
oAngieCtxt.RuleConditions.InsertOnSubmit(oRuleCon);
}
else
{
...
}
}
//add all new rule conditions
rule.RuleConditions.AddRange(newRuleConditions);

Categories