Updating entity using DBcontext in entity framewok is not working - c#

I have a project I am using a database that is connected thru the entity data model and I am using the DBcontext to create and update entities.
My Create method (below) is working fine.
[HttpPost]
public IHttpActionResult PostCustomer([FromBody] Customer Customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
using (var dbCtx = new CustomerDBEntities())
{
dbCtx.Customers.Add(Customer);
dbCtx.SaveChanges();
}
return CreatedAtRoute("DefaultApi", new { id = Customer.id }, Customer);
}
But my update method is doing nothing. I am not getting an error or anything just nothing seems to happen. and it is not updating the values.
The code is this
[HttpPut]
public IHttpActionResult UpdateCustomer([FromBody] Customer Customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Customer cust;
var ctx = new CustomerDBEntities();
cust = ctx.Customers.Where(s => s.id == Customer.id).FirstOrDefault<Customer>();
if (cust != null)
{
cust.Customer_Name = Customer.Customer_Name;
cust.email = Customer.email;
cust.Customer_address = Customer.Customer_address;
}
ctx.Entry(cust).State = System.Data.EntityState.Modified;
ctx.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = Customer.id }, Customer);
}
When I was using an SQL command before to go directly to database it was working fine but ever since I changed it it stopped working.
Any help would be much appreciated.

Remove this line of code.
ctx.Entry(cust).State = System.Data.EntityState.Modified;
EF tracks the changes made to entities in the context, you do not need to tell it that it was modified.

Add changes at Property Level
context.Entry(Customer).Property(cust => cust.Customer_Name).IsModified = true;
More Details here https://msdn.microsoft.com/en-us/data/jj592677
Also similar question answered here https://stackoverflow.com/a/15339512/1481690

Related

Update Database in C# after using JsonPatchDocument.ApplyTo

So here is my problem. I have an httpPatch endpoint where I have to do an update.
Here is the code
[HttpPatch, Route("api/serversTarget/{id}")]
public IHttpActionResult updateEntity(int id, [FromBody] JsonPatchDocument<ServerTarget> patchEntity)
{
var entity = db.getAllServers().FirstOrDefault(s => s.id == id);
if (entity == null)
{
return NotFound();
}
patchEntity.ApplyTo(entity);
//UPDATE in Oracle Database
db.updateServerInDatabase(entity);
return Ok(entity);
}
I get all the db entries when the program starts and put them into a list (getAllServers()). My question is how do I know what changes have been made by patchEntity.ApplyTo() so I can update the database accordingly.

Maybe I misunderstood the update method of Entity Framework?

Using a Web API, I want to update one record and two m-to-n relation tables in the PUT method. For this I found the update method of Entity Framework. However, my code further down does nothing at all. Is it possible that I have fundamentally misunderstood something there?
[HttpPut("Roles/{roleID}")]
public async Task<ActionResult> UpdateRole(int roleID, Role updatedRole) {
// Validate data
if (roleID != updatedRole.ID)
return BadRequest("ID missmatch.");
if (!updatedRole.Validate(out string problems))
return BadRequest(problems);
// Apply modified relations
updatedRole.ApplyModifiedRelations();
// Setup db connection
MpaContext db = _mpaContext;
Response.RegisterForDispose(db);
// Save changes
db.Update(updatedRole);
// I've added these two afterwords, but it also doesn't update anything
if (updatedRole.HasModifiedClientIDs)
db.UpdateRange(updatedRole.ClientRoles);
if(updatedRole.HasModifiedViewerIDs)
db.UpdateRange(updatedRole.RoleViewers);
try {
await db.SaveChangesAsync();
} catch (Exception ex) {
return Problem(ex.Message);
}
return Ok();
}
public void ApplyModifiedRelations() {
if (HasModifiedClientIDs) {
ClientRoles = new List<ClientRole>(
_ClientIDs.Select(c => new ClientRole() { ClientID = c, RoleID = ID })
);
}
if (HasModifiedViewerIDs) {
RoleViewers = new List<RoleViewer>(
_ViewerIDs.Select(v => new RoleViewer() { RoleID = ID, ViewerID = v })
);
}
}
I think your object didn't exist in db context (because you get it from request). So EF can't update it.
Try this
db.Entry(updatedRole).State = EntityState.Modified;
db.SaveChanges();
I found the solution. You have to actually load the relationship before updating it. I modified my ApplyModifiedRelations method accordingly:
public async Task ApplyModifiedRelations(MpaContext db) {
if (HasModifiedClientIDs) {
await db.Entry(this).Collection(r => r.ClientRoles).LoadAsync();
ClientRoles = new List<ClientRole>(
_ClientIDs.Select(c => new ClientRole() { ClientID = c, RoleID = ID })
);
}
if (HasModifiedViewerIDs) {
await db.Entry(this).Collection(r => r.RoleViewers).LoadAsync();
RoleViewers = new List<RoleViewer>(
_ViewerIDs.Select(v => new RoleViewer() { RoleID = ID, ViewerID = v })
);
}
}
I also moved that method call below the db.Update call. But I don't know, if this makes any difference.

ASP.NET Entity Framework API Update single column

I am using ASP.NET MVC Entity Framework and I created an API controller, now I want to add a method that is basically a copy of the put method, however I want to adjust this method so it updates a single column
[ResponseType(typeof(void))]
[Authorize]
public IHttpActionResult PutUser(int id, Users user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != user.id)
{
return BadRequest();
}
db.Entry(user).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!UsersExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
each user in my User class has an email and column called isOnline, for this method I want to update the isOnline to true based on the email.
The examples I have seen online are for non API controllers. Please Help!
Your subject is partial update in Entity Framework, following is an example:
var user= new User() {Id = id, TargetColumn = "test"};
context.Users.Attach(user);
var entry = context.Entry(user);
entry.Property(e => e.TargetColumn ).IsModified = true;;

Partial update in Web API is not working

I created a post method in my Web API to do a partial update of one table - to change Order Status field in the table. here is what I got so far:
public IHttpActionResult UpdateOrderStatus(Order ord)
{
try
{
if (!ModelState.IsValid)
{
throw new ProcessException("One or more values are invalid, please check.");
}
using (MyContext ctx = new MyContext())
{
ord.StatusID = 3;
ctx.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = ord.OrderID }, ord);
}
}
catch (Exception ex)
{
throw new ProcessException(ex.Message);
}
}
I am stepping through the code and everything seems to be working - no errors, but the database is not getting updated. What am I doing wrong?
Update:
Set the StatusID in the object BEFORE passing it to the Web API method:
var ord = { "OrderID": 1, "OrderDate": CurrentDate, "StatusID": 3};
public IHttpActionResult UpdateOrderStatus(Order ord)
{
try
{
if (!ModelState.IsValid)
{
throw new ProcessException("One or more values are invalid, please check.");
}
using (MyContext ctx = new MyContext())
{
ctx.Entry(ord).State = EntityState.Modified;
ctx.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = ord.OrderID }, ord);
}
}
catch (Exception ex)
{
throw new ProcessException(ex.Message);
}
}
If you're using EntityFramework then you need to inform the context about the Order object you are updating. In EF6 you would typically have a DbSet property on the context called Orders, so I'd advise adding ctx.Orders.Attach(Order) before you set the StatusID
Try this code:
Get orderEntity from database by comparing with ord.OrderID, Then update StatusID of that record.
using (MyContext ctx = new MyContext())
{
var orderEntity = ctx.Order.FirstOrDefault(x=> x.OrderID == ord.OrderID);
orderEntity.StatusID = 3;
ctx.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = ord.OrderID }, ord);
}

Saving Entity Framework object is deleting existing one

I have an information page which is being posted to database using Entity Framework. Everything is fine but when I initially enter a record and hit save twice, the record is deleted from database (it actually saves after first save click). This problem doesn't reflect for modifying and occurs for new entry.
Here is my code
public async Task<IHttpActionResult> Put(int id, [FromBody]CandidateLanding landing)
{
var result = await candidateContext.CandidateLanding
.Where(x => x.UserID == id)
.AsNoTracking()
.SingleOrDefaultAsync();
if (result != null)
{
if (landing.ID == 0)
{
landing.ID = result.ID;
}
}
if (ModelState.IsValid)
{
if (landing.ID > 0)
{
candidateContext.Entry(landing).State = EntityState.Modified;
}
else
{
landing.UserID = id;
candidateContext.CandidateLanding.Add(landing);
}
await candidateContext.SaveChangesAsync();
}
return CreatedAtRoute("DefaultApi", new { id = landing.ID }, landing);
}

Categories

Resources