Updates are not factored to the database using Entity Framework - entity-framework

Following code doesn't update my database for the record found and when looking at Azure SQL Profiler I see only this update statement.
update [dbo].[Identities]
set #p = 0
where ([Id] = #0)
and the code:
using (var db = new context())
{
var member = db.Identities.Include("Member").Include("Roles")
.FirstOrDefault(i => id.Value == i.nameidentifier && i.identityprovider == provider.Value);
if (member != null)
{
member.LastLoggedIn = DateTime.UtcNow;
db.SaveChanges();
}
}

Related

Remove and Insert in table , Removing previous data using Entity frame work in asp.net core

When trying to insert "FromCompany" data to "ToCompany" after saveChanges(); it deleted "FromCompany" data.
I am trying to delete old data , and copy the data from another company to mycompany, but it deleting the data from that comapny after saving it in my company.
This is the example code:
foreach (var data in ctx.AllData.Where(a => a.CompanyId == toCompanyId).Select(a => a).ToList())
{
ctx.AllData.Remove(data);
}
ctx.SaveChanges();
var alldata = ctx.AllData.Where(a => a.CompanyId == fromCompanyId ).Select(a => a).ToList();
foreach (var data in alldata)
{
var model = new AllData();
data.CompanyId = toCompanyId;
model.CompanyId = data.CompanyId;
model.CategoryId = data.CategoryId;
model.OtherFields = data.OtherFields;
ctx.AllData.Add(model);
}
ctx.SaveChanges();
In the second foreach you are changing the data.CompanyId. Then calling ctx.SaveChanges you are changing all companies with fromCompanyId. Try to remove that line, like this:
foreach (var data in ctx.AllData.Where(a => a.CompanyId == toCompanyId).Select(a => a).ToList())
{
ctx.AllData.Remove(data);
}
ctx.SaveChanges();
var alldata = ctx.AllData.Where(a => a.CompanyId == fromCompanyId ).Select(a => a).ToList();
foreach (var data in alldata)
{
var model = new AllData();
model.CompanyId = toCompanyId;
model.CategoryId = data.CategoryId;
model.OtherFields = data.OtherFields;
ctx.AllData.Add(model);
}
ctx.SaveChanges();
While you are calling ctx.SaveChanges you are saving all changes were performed in all context's data.

MVC 4 EF Update failed Object Already Exists In The ObjectStateManager

I have this relationship for my tables. Activity, Workstation, Platform, Part are the lookup tables.
I have ActivitWorkstation that contains (ActivityId, WorkstationId) foreign keys to Activity and Workstation tables.
I also have PlatformPart that contains (PlatformId, PartId) foreign keys to Platform and Part tables.
Lastly I have PartStaging table that has (ActivityWorkstationId, PlatformPartId) foreign keys to ActivityWorkstation and PlatformPart tables.
Below is my PartStaging Edit method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(PartStagingVM partstagingvm)
{
if (ModelState.IsValid)
{
PartStaging partstaging = new PartStaging();
var activityWorkstation = db.ActivityWorkstations.FirstOrDefault(aw => aw.ActivityId == partstagingvm.ActivityId && aw.WorkstationId == partstagingvm.WorkstationId);
if (activityWorkstation == null)
{
activityWorkstation = new ActivityWorkstation
{
ActivityId = partstagingvm.ActivityId,
WorkstationId = partstagingvm.WorkstationId
};
db.Entry(activityWorkstation).State = EntityState.Added;
}
var platformPart = db.PlatformParts.FirstOrDefault(pp => pp.PlatformId == partstagingvm.PlatformId && pp.PartId == partstagingvm.PartId);
if (platformPart == null)
{
platformPart = new PlatformPart
{
PlatformId = partstagingvm.PlatformId,
PartId = partstagingvm.PartId
};
db.Entry(platformPart).State = EntityState.Added;
}
var partStaging = db.PartStagings.FirstOrDefault(ps => ps.ActivityWorkstationId == activityWorkstation.Id && ps.PlatformPartId == platformPart.Id);
if (partStaging != null && partStaging.Id != partstagingvm.Id)
{
TempData["Message"] = "The record already exists.";
}
else
{
partstaging.Id = partstagingvm.Id;
partstaging.ActivityWorkstationId = activityWorkstation.Id;
partstaging.PlatformPartId = platformPart.Id;
partstaging.Description = partstagingvm.Description;
db.Entry(partstaging).State = EntityState.Modified;
db.SaveChanges();
TempData["Message"] = "The record has been modified.";
}
return RedirectToAction("Edit");
}
return View(partstagingvm);
}
I can edit ActivityWorkstation. I can edit PlatformPart. It prevents me from updating when the record already exists. But I have a problem when editing the Description. It's supposed to be the simplest update since all I have to do is to assign:
partstaging.Description = partstagingvm.Description
But when I submit, I get this error:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
Source Error:
Line 216: partstaging.Description = partstagingvm.Description;
Line 217:
Line 218: db.Entry(partstaging).State = EntityState.Modified;
Line 219: db.SaveChanges();
Line 220:
What am I missing?

how to update a record in database using LINQ?

I want to do the following in LINQ:
update [dbo].[AdminLogin] set [ADMIN_PASSWORD] = 'abc' where [ADMIN_ID] = 1
where i get the admin password from a model and the admin id is stored in a variable:
var userid = (from m in db.RequestPasswordReset
where m.Id == Unid
select m.UserId).FirstOrDefault();
How to do it?
To update an entity you must have to specify the Modified state.
using (var db= new DbContext())
{
var entity= db.AdminLogin.Where(x => x.ADMIN_ID == userid ).SingleOrDefault();
entity.ADMIN_PASSWORD = 'abc';
db.Entry(entity).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
see details here
use this code:
using (var context = new YourContext())
{
var res = context.AdminLogin.Where(x => x.ADMIN_ID == userid ).SingleOrDefault();
res.ADMIN_PASSWORD = 'abc';
context.SaveChanges();
}
You can try this:
var user = db.AdminLogin.FirstOrDefault(x => x.ADMIN_ID == id);
user.ADMIN_PASSWORD = 'abc';
db.SaveChanges();
userid.ADMIN_PASSWORD= 'abc';
db.SaveChanges(); //better then db.SubmitChanges() in some case
If you using linQ.dbml file then you have to write like this:
using (var db= new DbContext())
{
var entity= db.AdminLogin.Where(x => x.ADMIN_ID == userid ).FirstOrDefault();
entity.ADMIN_PASSWORD = 'abc';
db.SubmitChanges();
}

Not able to access list of record in EF

Here is the problem I am trying to access some records from the data base based on one field . The field I am using is audit_id having type GUID .
but the line does not returning any data
var audits = ctx.Audits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
Here is a my full code to update mass records in the database using EF
//will select auditId from the List
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x=>x.AuditId).ToList();
using (var ctx = new AuditEntities())
{
var audits = ctx.Audits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
audits.ForEach(x => x.working_list = false);
ctx.SaveChanges();
}
In case of single record it return data from database
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x => x.AuditId).ToList();
Guid tempAuditId = lstAudits[0];
// lstAudits.ForEach(x => x.ToString().ToUpper());
using (var ctx = new AuditEntities())
{
var audits = (from au in ctx.Audits
where au.audit_id == tempAuditId
select au).ToList();
//foreach(Audit audit in audits){
//}
audits[0].working_list = false;
ctx.SaveChanges();
}
Finally I got the answer here is the updated code which is working fine .I just took some intermediate result in a temporary variable and it started working as expected
//will select auditId from the List
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x => x.AuditId).ToList();
using (var ctx = new AuditEntities())
{
var tempAudits = ctx.Audits.ToList();
var audits = tempAudits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
audits.ForEach(x => x.working_list = false);
ctx.SaveChanges();
}

Entity Framework savechanges() update delete insert

I want my SaveChanges() function to update a record in my database and if the return value is '1' which is coming from my stored procedure then and only then 'delete' command (stored procedure) should not be executed.
Now, the problem is db.SaveChanges() (an instance of ObjectContext) is updating my record successfully but after updating, it executes the delete command. How should I tell my function that not to execute delete command.
using (var db = new PRLAdminEntities())
{
bool isExists = false;
string lastExisting = string.Empty;
string errorString = string.Empty;
db.Connection.Open();
trans = db.Connection.BeginTransaction();
//accounts to be sent back to client
var countriesToSendBack = new List<Polo.Common.Shared.Entities.Country>();
//process each account requiring database update
if (request.CountriesToUpdate != null)
{
foreach (var country in request.CountriesToUpdate)
{
//countriesToSendBack.Remove(country);
var temp = from row in db.Countries where row.Name.ToUpper() == country.Name.ToUpper() select row;
if (temp.Count<Polo.Common.Shared.Entities.Country>() > 0 && country.ChangeTracker.State == ObjectState.Added)
{
countriesToSendBack.Add(country);
db.Countries.ApplyChanges(country);
isExists = true;
lastExisting = country.Name;
errorString += country.Name + ", ";
//db.GetAllCountries();
//break;
continue;
}
if (country.ChangeTracker.State == ObjectState.Deleted)
{
db.DeleteObject(country);
}
//if a change or modification (not a delete)
if (country.ChangeTracker.State != ObjectState.Deleted)
{
//this account should be sent back
if (!countriesToSendBack.Contains((country)))
countriesToSendBack.Add(country);
if (country.Active == false)
{
db.Countries.ApplyCurrentValues(country);
}
}
//apply all changes
db.Countries.ApplyChanges(country);
}
if (isExists)
{
//response.Success = false;
//errorString.Replace(", " + lastExisting + ",", " & " + lastExisting);
//response.FaultMessage = "Duplicate Records";
}
}
//save all changes
int total = db.SaveChanges();
response.Success = true;
foreach (var countryItem in countriesToSendBack)
{
countryItem.Id = (from row in db.Countries where row.Name.ToUpper() == countryItem.Name.ToUpper() select row.Id).FirstOrDefault();
}
trans.Commit();
//refresh the account data which gets timestamp etc
db.Refresh(RefreshMode.StoreWins,countriesToSendBack);
//set the response values
response.Countries = countriesToSendBack;
}
}
Perhaps I misread your question, I do not totally get what you are trying to do.
But why not call SaveChanges() after the change and when all checks are positive perform a remove() and call savechanges() again?
There is no harm is calling SaveChanges() multiple times. It will mirror it's data to your database. If you perform a remove it will try to delete it in your database. That's the nice thing about it.. it does what you tell it to do ;-)