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

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.

Related

How to update multiple rows of a database table in ASP.NET Core

I want to update multiple rows in ASP.NET Core, but I get an error:
InvalidOperationException: The entity type 'EntityQueryable' was not found. Ensure that the entity type has been added to the model.
This is my code:
var data = _db.UserTable.Where(a => a.CityIDn == selectedid);
foreach (var items in data)
{
await Task.Run(() =>
{
items.CityID = 2;
});
_db.Update(data);
await _db.SaveChangesAsync();
}
Try this for multiple rows:
var data = _db.UserTable.Where(a => a.CityIDn == selectedid).ToList();
foreach (var item in data)
{
item.CityID = 2;
_db.UserTable.Update(item);
}
await _db.SaveChangesAsync();
And for one record, try like this:
var data = _db.UserTable.Where(a => a.CityIDn == selectedid).FirstOrDefault();
if(data != null)
{
data.CityID = 2;
_db.UserTable.Update(data );
await _db.SaveChangesAsync();
}
The content of Update should be items, it worked for me, you can have a try.
var data = _db.UserTable.Where(a => a.CityIDn == selectedid).ToList();
foreach (var items in data)
{
await Task.Run(() =>
{
items.CityID = 2;
});
_db.Update(items);
await _db.SaveChangesAsync();
}

UpdateRange method of Entity Framework Core does not work

The UpdateRange method of Entity Framework Core is used here to update multiple records but it is not working.
My code is:
var dept1 = new Department()
{
Id = 8,
Name = "New Designing"
};
var dept2 = new Department()
{
Id = 9,
Name = "New Research"
};
var dept3 = new Department()
{
Id = 102,
Name = "New HR"
};
List<Department> modifiedDept = new List<Department>() { dept1, dept2, dept3 };
using (var context = new CompanyContext())
{
context.UpdateRange(modifiedDept);
await context.SaveChangesAsync();
}
And the error I get is:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 'Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.'
What should be done in this case?
You are supposed to get data from database and modify data. Not creating new class.
using (var context = new JobContext())
{
var depts = context.Department.Where(x => x.Id > 1).AsQueryable();
depts.Where(x => x.Id == 2).FirstOrDefault().Name = "New Designing";
depts.Where(x => x.Id == 3).FirstOrDefault().Name = "New Research";
depts.Where(x => x.Id == 4).FirstOrDefault().Name = "New HR";
context.UpdateRange(depts);
context.SaveChanges();
}
Before
After

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();
}

Merge Self-tracking entities

Graph of objects stored in the database and the same object graph is serialized into a binary package. Package is transmitted over the network to the client, then it is necessary to merge data from the package and data from the database.
Source code of merge:
//objList - data from package
var objectIds = objList.Select(row => row.ObjectId).ToArray();
//result - data from Database
var result = SomeService.Instance.LoadObjects(objectIds);
foreach (var OSobj in objList)
{
var obj = result.Objects.ContainsKey(OSobj.ObjectId)
? result.Objects[OSobj.ObjectId]
: result.Objects.CreateNew(OSobj.ObjectId);
var targetObject = result.DataObjects.Where(x => x.ObjectId == OSobj.ObjectId).FirstOrDefault();
targetObject.StopTracking();
var importedProperties = ImportProperties(targetObject.Properties, OSobj.Properties);
targetObject.Properties.Clear();
foreach (var property in importedProperties)
{
targetObject.Properties.Add(property);
}
targetObject.StartTracking();
}
return result;
And code of ImportProperties method:
static List<Properties> ImportProperties(
IEnumerable<Properties> targetProperties,
IEnumerable<Properties> sourceProperties)
{
Func<Guid, bool> hasElement = targetProperties
.ToDictionary(e => e.PropertyId, e => e)
.ContainsKey;
var tempTargetProperties = new List<Properties>();
foreach (var sourceProperty in sourceProperties)
{
if (!hasElement(sourceProperty.PropertyId))
{
sourceProperty.AcceptChanges();
tempTargetProperties.Add(sourceProperty.MarkAsAdded());
}
else
{
sourceProperty.AcceptChanges();
tempTargetProperties.Add(sourceProperty.MarkAsModified());
}
}
return tempTargetProperties;
}
Server save incoming changes like this :
_context.ApplyChanges("OSEntities.Objects", entity);
_context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
When the server tries to save the changes occur exception:
AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
But if I change the code of ImportProperties method, the error does not occur and the changes are saved successfully:
static List<Properties> ImportProperties(
IEnumerable<Properties> targetProperties,
IEnumerable<Properties> sourceProperties)
{
Func<Guid, bool> hasElement = targetProperties.ToDictionary(e => e.PropertyId, e => e).ContainsKey;
var tempTargetProperties = new List<Properties>();
foreach (var sourceProperty in sourceProperties)
{
if (!hasElement(sourceProperty.PropertyId))
{
var newProp = new Properties
{
ElementId = sourceProperty.ElementId,
Name = sourceProperty.Name,
ObjectId = sourceProperty.ObjectId,
PropertyId = sourceProperty.PropertyId,
Value = sourceProperty.Value
};
tempTargetProperties.Add(newProp);
}
else
{
var modifiedProp = new Properties
{
ElementId = sourceProperty.ElementId,
Name = sourceProperty.Name,
ObjectId = sourceProperty.ObjectId,
PropertyId = sourceProperty.PropertyId,
Value = sourceProperty.Value
};
modifiedProp.MarkAsModified();
tempTargetProperties.Add(modifiedProp);
}
}
return tempTargetProperties;
}
Why is there an exception?
When you transport an object graph (Entity with n-level deep navigation properties) to a client application the entities will record any changes made in their respective change trackers. When entity (or object graph) is sent back to the server side of the application basically all you need to do is:
try
{
using(Entities context = new Entities())
{
context.ApplyChanges(someEntity);
context.SaveChanges();
}
}
catch
{
...
}
I don't see the need of all the code above you posted. What are you trying to achieve with that code?