I have the following issue on update of the entities. Given below is my WCF method. (Update is called by public Save method after determining if it is update or add)
protected bool UpdateSalesMaster(SalesMaster order)
{
using (var context = new MyContext())
{
SalesMaster original = context.SalesMasters.FirstOrDefault(o => o.OrderID == order.OrderID);
if (original != null)
{
context.Entry(original).CurrentValues.SetValues(order);
foreach (SalesDetail detail in order.SalesDetails)
{
if (detail.OrderDetailID == 0)
context.SalesDetails.Add(detail);
else
{
SalesDetails originalDetail = context.SalesDetails.FirstOrDefault(o => o.OrderDetailID == detail.OrderDetailID);
if (originalDetail != null)
context.Entry(originalDetail).CurrentValues.SetValues(detail);
}
}
context.SaveChanges();
return true;
}
else
{
throw new FaultException(string.Format("Invalid Order specified: {0}", order.OrderID));
}
}
}
When I just update the OrderDate in SalesMaster and don't change any in the detail, an update query is fired to the database for detail. I expected to see Update query only for SalesMaster.
Can someone let me know what am I doing wrong here? I don't want to fire update queries to the DB if nothing is changed.
I use the approach of getting the original value from the database to determine if any values are updated using context.Entry(originalDetail).CurrentValues.SetValues(detail);
I also override the SaveChanges to set the LastModified date by checking for IAuditable implementation of the entity. This is when I find that the state of the detail entity is identified as modified. But the only update that happens in the DB is LastModifiedBy which was updated in my save changes. I am not sure how it was set to state of Modified when nothing changed in detail.
public override int SaveChanges()
{
var changeSet = ChangeTracker.Entries<IAuditable>();
if (changeSet != null)
{
foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
{
if (entry.State == EntityState.Added)
entry.Entity.DateCreated = DateTime.Now;
if (entry.State == EntityState.Modified)
{
entry.Property(a => a.CreatedByUser).IsModified = false;
entry.Property(a => a.DateCreated).IsModified = false;
}
entry.Entity.DateModified = DateTime.Now;
}
}
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
throw ex;
}
}
My solution structure is:
Client - Windows forms UI
Entities - POCO as seperate library
WCF - All business logic, add, update, delete of objects.
Data - Entity Framework context with Fluent mapping.
Depending on how you set up you POCOs, EF will default to one of two ways to check changes on an entity.
If ALL your POCOs properties are virtual, EF will use proxy object that inherit your POCO type, with all the properties overridden to track changes.
I assume that in this circumstance, using SetValues on the whole object WILL trigger the dirty flag, that will cause EF to generate an Update query to the database.
If your are not using proxies, your IAuditable implementation would be the primary suspect as brumScouse suggested.
Related
I have a code block which checks whether an entity is being tracked by my context. If it is, I need to detach it. This works for a given T type.
public virtual async Task<bool> InsertOrUpdate(TE entity)
{
if (entity.Id == 0 || entity.Id == ModelState.New)
{
// attach new entity
_context.Entry(entity).State = EntityState.Added;
}
else
{
// Sometimes when you want to update a detached entity, before attempting to attach it (by setting the .State property),
// you first need to make sure the entity isn't already attached and being tracked. If this is the case, the existing entity
// needs to be detached, and the updated entity, attached.
var attachedEntity = _context.ChangeTracker.Entries<TE>().FirstOrDefault(e => e.Entity.Id == entity.Id);
if (attachedEntity != null)
{
// the entity you want to update is already attached, we need to detach it and attach the updated entity instead
_context.Entry<TE>(attachedEntity.Entity).State = EntityState.Detached;
}
_context.Entry<TE>(entity).State = EntityState.Modified; // Attach entity, and set State to Modified.
_context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
_context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
}
return await _context.SaveChangesAsync() > 0;
}
I now need to change the method so that it fetches all objects of type IEntity within the given T entity parameter and then do the same logic for each object found, but I'm having trouble with setting the ChangeTracker.Entries as I need to set the T type to the current selected type within the foreach. I have no idea how to do this.
public virtual async Task<bool> InsertOrUpdate(TE entity)
{
//// Find all instances of IEntity within TE:
//// * IF entity is new we set State to EntityState.Added (INSERT)
//// * IF entity is existing, we set State to EntityState.Modified (UPDATE)
List<IEntity> found = FindAllInstances<IEntity>(entity);
foreach (IEntity ent in found)
{
if (entity.Id == 0 || entity.Id == ModelState.New)
{
// attach new entity
_context.Entry(entity).State = EntityState.Added;
}
else
{
// Sometimes when you want to update a detached entity, before attempting to attach it (by setting the .State property),
// you first need to make sure the entity isn't already attached and being tracked. If this is the case, the existing entity
// needs to be detached, and the updated entity, attached.
var attachedEntity = _context.ChangeTracker.Entries<TE>().FirstOrDefault(e => e.Entity.Id == entity.Id);
if (attachedEntity != null)
{
// the entity you want to update is already attached, we need to detach it and attach the updated entity instead
_context.Entry<TE>(attachedEntity.Entity).State = EntityState.Detached;
}
_context.Entry<TE>(entity).State = EntityState.Modified; // Attach entity, and set State to Modified.
_context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
_context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
}
}
return await _context.SaveChangesAsync() > 0;
}
You could use the inner context wich is an ObjectContext.
var ctx = ((IObjectContextAdapter)_context).ObjectContext;
And then call ctx.Detach() on whatever entity you want. Fortunately this is not a generic method.
You can also get a reference to an ObjetStateManager from the ObjectContext and use it to do whatever state change you want.
More informations:
https://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.objectstatemanager(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.data.objects.objectstatemanager(v=vs.110).aspx
I am trying to update a record using Entity Framework 6, code-first, no fluent mapping or a tool like Automapper.
The entity(Employee) has other composite properties associated with it like Addreess(collection), Department
It is also inherited from a base called User
The save method is as follows, with _dbContext being the DbConext implementation
public bool UpdateEmployee(Employee employee)
{
var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
if (entity == null)
{
_dbContext.Employees.Add(employee);
}
else
{
_dbContext.Entry(employee).State = EntityState.Modified; // <- Exception raised here
_dbContext.Employees.Attach(employee);
}
return _dbContext.SaveChanges() > 0;
}
I keep getting the error:
Attaching an entity of type failed because another entity of the same
type already has the same primary key value. This can happen when
using the 'Attach' method or setting the state of an entity to
'Unchanged' or 'Modified' if any entities in the graph have
conflicting key values. This may be because some entities are new and
have not yet received database-generated key values. In this case use
the 'Add' method or the 'Added' entity state to track the graph and
then set the state of non-new entities to 'Unchanged' or 'Modified' as
appropriate.
I have tried the following:
Attaching before setting to EntityState.Modified
Adding AsNoTracking() on querying if the object exists(No exception but DB is not updated) - https://stackoverflow.com/a/23228001/919426
Saving using the base entity _dbContext.Users instead of the Employee entity - https://stackoverflow.com/a/25575634/919426
None of which is working for me now.
What could I have gotten wrong for some of those solutions not to work in my situation?
EF already includes a way to map properties without resorting to Automapper, assuming you do not have navigation properties to update:
public bool UpdateEmployee(Employee employee)
{
var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
if (entity == null)
{
_dbContext.Employees.Add(employee);
}
else
{
_dbContext.Entry(entity).CurrentValues.SetValues(employee);
}
return _dbContext.SaveChanges() > 0;
}
This usually generates a better SQL statement since it will only update the properties that have changed.
If you still want to use the original method, you'll get rid of entity from the context, either using AsNoTracking (not sure why it didn't update in your case, it should have no effect, so the problem might be something else) or as modifying your query to prevent it from materializing the entity in the first place, using something like bool exists = dbContext.Employees.Any(c => c.Id == employee.Id) for example.
This worked for myself
var aExists = _db.Model.Find(newOrOldOne.id);
if(aExists==null)
{
_db.Model.Add(newOrOldOne);
}
else
{
_db.Entry(aExists).State = EntityState.Detached;
_db.Entry(newOrOldOne).State = EntityState.Modified;
}
I've encountered the same thing when using a repository and unit of work pattern (as documented in the mvc4 with ef5 tutorial).
The GenericRepository contains an Update(TEntity) method that attempts to Attach then set the Entry.State = Modified. The up-voted 'answer' above doesn't resolve this if you are going to stick to the uow / repo pattern.
I did attempt to use the detach process prior to the attach, but it still failed for the same reason as indicated in the initial question.
The reason for this, it turns out, is that I was checking to see if a record existed, then using automapper to generate an entity object from my dto prior to calling update().
By checking for the existance of that record, i put the entity object in scope, and wasn't able to detach it (which is also the reason the initial questioner wasn't able to detach)... Tt tracked the record and didn't allow any changes after I automapper'ed the dto into an entity and then attempted to update.
Here's the generic repo's implementation of update:
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
This is my PUT method (i'm using WebApi with Angular)
[HttpPut]
public IHttpActionResult Put(int id, Product product)
{
IHttpActionResult ret;
try
{
// remove pre-check because it locks the record
// var e = unitOfWork.ProductRepository.GetByID(id);
// if (e != null) {
var toSave = _mapper.Map<ProductEntity>(product);
unitOfWork.ProductRepository.Update(toSave);
unitOfWork.Save();
var p = _mapper.Map<Product>(toSave);
ret = Ok(p);
// }
// else
// ret = NotFound();
}
catch (DbEntityValidationException ex)
{
ret = BadRequest(ValidationErrorsToMessages(ex));
}
catch (Exception ex)
{
ret = InternalServerError(ex);
}
return ret;
}
As you can see, i've commented out my check to see if the record exists. I guess i'll see how it works if I attempt to update a record that no longer exists, as i no longer have a NotFound() return opportunity.
So to answer the initial question, i'd say don't look for entity==null before making the attempt, or come up with another methodology. maybe in my case, i could dispose of my UnitOfWork after discovery of the object and then do my update.
You need to detach to avoid duplicate primary key exception whist invoking SaveChanges
db.Entry(entity).State = EntityState.Detached;
I'm new to using entity as a data layer between MVC and SQL Server, so I apologize up front if what I'm doing is bad practice.
Let me start by sharing the code that is handling the update.
Update Delivery:
public bool One(Delivery toUpdate)
{
using (var dbContext = new FDb())
{
try
{
var deliveryInDb = this.dbTable(dbContext).Single(x => x.DeliveryId == toUpdate.DeliveryId);
dbContext.Entry(deliveryInDb).CurrentValues.SetValues(toUpdate);
//removal first
List<DeliveryDay> currentDays = FEngineCore.DeliveryDay.Get.ForValue((x => x.DeliveryId), toUpdate.DeliveryId);
List<DeliveryTime> currentTimes = FEngineCore.DeliveryTime.Get.ForValue((x => x.DeliveryId), toUpdate.DeliveryId);
//remove delivery days that are not needed
foreach (var curDay in currentDays)
{
if (!toUpdate.DeliveryDays.Select(x => x.DeliveryDayId).Contains(curDay.DeliveryDayId))
{
FEngineCore.DeliveryDay.Delete.One((x => x.DeliveryDayId), curDay.DeliveryDayId);
deliveryInDb.DeliveryDays.Remove(curDay);
}
}
//remove delivery times that are not needed
foreach (var curTime in currentTimes)
{
if (!toUpdate.DeliveryTimes.Select(x => x.DeliveryTimeId).Contains(curTime.DeliveryTimeId))
{
FEngineCore.DeliveryTime.Delete.One((x => x.DeliveryTimeId), curTime.DeliveryTimeId);
deliveryInDb.DeliveryTimes.Remove(curTime);
}
}
foreach (var day in toUpdate.DeliveryDays)
{
if (day.DeliveryDayId == 0)
{
dbContext.DeliveryDays.Add(day);
}
else
{
if (dbContext.DeliveryDays.Local.Any(e => e.DeliveryDayId == day.DeliveryDayId))
{
dbContext.Entry(dbContext.DeliveryDays.Local.First(e => e.DeliveryDayId == day.DeliveryDayId)).CurrentValues.SetValues(day);
dbContext.Entry(dbContext.DeliveryDays.Local.First(e => e.DeliveryDayId == day.DeliveryDayId)).State = EntityState.Modified;
}
else
{
DeliveryDay modDay = new DeliveryDay
{
DayOfWeek = day.DayOfWeek,
DeliveryDayId = day.DeliveryDayId,
DeliveryId = day.DeliveryId,
Interval = day.Interval
};
dbContext.DeliveryDays.Attach(modDay);
dbContext.Entry(modDay).State = EntityState.Modified;
}
deliveryInDb.DeliveryDays.Add(day);
}
}
foreach (var time in toUpdate.DeliveryTimes)
{
if (time.DeliveryTimeId == 0)
{
dbContext.DeliveryTimes.Add(time);
}
else
{
if (dbContext.DeliveryTimes.Local.Any(e => e.DeliveryTimeId == time.DeliveryTimeId))
{
dbContext.Entry(dbContext.DeliveryTimes.Local.First(e => e.DeliveryTimeId == time.DeliveryTimeId)).CurrentValues.SetValues(time);
dbContext.Entry(dbContext.DeliveryTimes.Local.First(e => e.DeliveryTimeId == time.DeliveryTimeId)).State = EntityState.Modified;
}
else
{
DeliveryTime modTime = new DeliveryTime
{
DeliveryId = time.DeliveryId,
DeliveryLocationId = time.DeliveryLocationId,
DeliveryTimeId = time.DeliveryTimeId,
DropoffTime = time.DropoffTime
};
dbContext.DeliveryTimes.Attach(modTime);
dbContext.Entry(modTime).State = EntityState.Modified;
}
deliveryInDb.DeliveryTimes.Add(time);
}
}
dbContext.SaveChanges();
dbContext.Entry(deliveryInDb).State = EntityState.Detached;
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return false;
}
}
}
Let me continue by explaining that the delivery object has 2 children; DeliveryTime and DeliveryDay. The issue that arises happens when I try to remove one deliveryTime and modify nothing else. The end result of running the code normally (not in debug) is that the deliveryTime is in fact not removed. Here's the interesting thing guys, when I debug it and go through the break points, everything works as expected!
Let me continue by posting the code that is running behind the removal method of the deliveryTime (actually all entity objects in my system).
public bool One<V>(Expression<Func<T, V>> property, V value) where V : IComparable
{
using (var dbContext = new FoodsbyDb())
{
try
{
T toDelete;
//get the body as a property that represents the property of the entity object
MemberExpression entityPropertyExpression = property.Body as MemberExpression;
//get the parameter that is representing the entity object
ParameterExpression entityObjectExpression = (ParameterExpression)entityPropertyExpression.Expression;
//represent the value being checked against as an expression constant
Expression valueAsExpression = Expression.Constant(value);
//check the equality of the property and the value
Expression equalsExpression = Expression.Equal(entityPropertyExpression, valueAsExpression);
//create an expression that takes the entity object as a parameter, and checks the equality using the equalsExpression variable
Expression<Func<T, bool>> filterLambda = Expression.Lambda<Func<T, bool>>(equalsExpression, entityObjectExpression);
toDelete = this.dbTable(dbContext)
.SingleOrDefault(filterLambda);
if (toDelete != null)
{
this.dbTable(dbContext)
.Remove(toDelete);
dbContext.SaveChanges();
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return false;
}
}
}
The code above is obviously generic, and it handles all my entity objects. I have tested it in and out and know for sure the problem does not lie in there. I thought it would be helpful to post it so you all can have a full understanding of what's going on.
Here's my best guess as to what's going on:
The reference to the removed deliveryTime still exists when the database context is saved, but when I debug, the system has enough time to remove the context.
Here was one of my attempted solutions:
Remove all references to the children objects immediately after setting currentDays and currentTimes and then proceeding to add them back to deliveryInDb as you enumerate through them.
Because I am new to all of this, if you see some bad practice along with the solution, I wouldn't mind constructive criticism to improve my programming method.
I actually encountered this issue in a project at work. The project is an older MVC4 project using EF 6.1.
In our situation, a simple update attempting to set a related entity property to null was failing to actually set it to null while running the web app normally (in debug mode). When setting a break point on the line of code that sets the property to null the database would be updated as expected, though. So, the update was working when a break point was in place but not working when allowed to run normally.
Using an EF interceptor, we could see that, with the break point in place, the update query was going through as expected.
Now, in our situation the related entity was using the virtual keyword to allow for lazy loading. I think this is the root of the issue. When a break point is present, EF has enough time to both lazily load that related entity and evaluate whatever it needs to evaluate and finally set it to null. When running without a break point, I think EF gets caught up trying to lazily load that entity and therefore fails to think it needs to be updated. To be clear, I was both accessing the related entity property for the first time and setting it null using a one-liner of code.
foo.Bar = null;
I resolved this issue, in our scenario, by accessing that property at least once prior to setting it to null so that EF is forced to load it. With it loaded, setting it to null seems to work as intended now. So again, to be clear, I think the issue is a combo of lazy loading and the one-liner of code both accessing that property for the first time and assigning it to null.
It appears that you're using multiple instances of your DbContext, which are not synchronized.
The solution would be to use a single instance, and pass that instance between your methods.
I'm having some trouble using a helper method to perform an update to a set of model objects. The table uses a lookup table to hold 5 records per agent/user. If I want to save the record for the agent, I need to save that record onto the AgentTransmission table, and up to 5 other records on the RelationshipCodeLookup table.
Since I have to do this five times per agent, and we must do the process in the Create and Edit methods, I created a helper method to save the records. This works fine during the create process as we're simply doing a DbContext.Add(). However when I need to perform an update, I get the error message
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
I think this has to do with the fact I'm passing the model object to my helper method, and therefore the DbContext thinking that it has two separate objects to keep track of. I say this because the lines of code that are commented out work just fine and allow me to save the object. Passing the object to the helper method, however, gets the above error.
Does anyone know of a way around this (using a helper method to perform an update)?
Controller Action
//Save relationship codes in lookup table
if (AgentTransmissionValidator.ValidateRelationshipCode(agenttransmission.RelationshipCode1))
{
//db.Entry(agenttransmission.RelationshipCode1).State = EntityState.Modified;
//db.SaveChanges();
SaveRelationshipCodes(agenttransmission.RelationshipCode1, agenttransmission.ID);
}
if (AgentTransmissionValidator.ValidateRelationshipCode(agenttransmission.RelationshipCode2))
{
//db.Entry(agenttransmission.RelationshipCode1).State = EntityState.Modified;
//db.SaveChanges();
SaveRelationshipCodes(agenttransmission.RelationshipCode2, agenttransmission.ID);
}
if (AgentTransmissionValidator.ValidateRelationshipCode(agenttransmission.RelationshipCode3))
{
//db.Entry(agenttransmission.RelationshipCode1).State = EntityState.Modified;
//db.SaveChanges();
SaveRelationshipCodes(agenttransmission.RelationshipCode3, agenttransmission.ID);
}
if (AgentTransmissionValidator.ValidateRelationshipCode(agenttransmission.RelationshipCode4))
{
//db.Entry(agenttransmission.RelationshipCode1).State = EntityState.Modified;
//db.SaveChanges();
SaveRelationshipCodes(agenttransmission.RelationshipCode4, agenttransmission.ID);
}
if (AgentTransmissionValidator.ValidateRelationshipCode(agenttransmission.RelationshipCode5))
{
//db.Entry(agenttransmission.RelationshipCode1).State = EntityState.Modified;
//db.SaveChanges();
SaveRelationshipCodes(agenttransmission.RelationshipCode5, agenttransmission.ID);
}
Helper Method
public void SaveRelationshipCodes(RelationshipCodeLookup relCode, int id)
{
if (relCode.AgentId == 0) relCode.AgentId = id;
relCode.LastChangeDate = DateTime.Now;
relCode.LastChangeId = Security.GetUserName(User);
//Check to see if record exists and if not add it
if (db.RelationshipCodeLookup.Find(id, relCode.RelCodeOrdinal) != null)
{
db.Entry(relCode).State = EntityState.Detached;
}
else
{
if(relCode.RelCodeOrdinal == 0) relCode.RelCodeOrdinal = FindOrdinal(relCode);
db.RelationshipCodeLookup.Add(relCode);
}
db.SaveChanges();
}
EDIT
After scouring the web I attempted to save via this method
//Check to see if record exists and if not add it
if (db.RelationshipCodeLookup.Find(id, relCode.RelCodeOrdinal) != null)
{
db.Entry(relCode).CurrentValues.SetValues(relCode);
}
else
{
Member 'CurrentValues' cannot be called for the entity of type 'RelationshipCodeLookup because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet<RelationshipCodeLookup>
However.... doing that only puts me back at the start with the following error on db.RelationshipCodeLookup.Attach(relCode);
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
Try this:
db.RelationshipCodeLookup.Attach(relCode);
db.Entry(relCode).State = EntityState.Modified;
For updates you want to attach the detached object then set it's state to modified.
The issue here seems to be that the Entity Framework cannot track two objects of the same kind at the same time. Because of that I find the solution to this problem more than a little weird. By calling .Find() on the DbContext and instantiating a second copy of the model object I was finally able to save. Seems to break all the rules the EF was laying out for me in the error messages, but hey it works.
public void SaveRelationshipCodes(int id, RelationshipCodeLookup relCode)
{
if (relCode.AgentId == 0) relCode.AgentId = id;
relCode.LastChangeDate = DateTime.Now;
relCode.LastChangeId = Security.GetUserName(User);
//Check to see if record exists and if not add it
if (db.RelationshipCodeLookup.Find(id, relCode.RelCodeOrdinal) != null)
{
//Need to call .Find to get .CurrentValues method call to work
RelationshipCodeLookup dbRelCode = db.RelationshipCodeLookup.Find(id, relCode.RelCodeOrdinal);
db.Entry(dbRelCode).CurrentValues.SetValues(relCode);
}
else
{
if(relCode.RelCodeOrdinal == 0) relCode.RelCodeOrdinal = FindOrdinal(relCode);
db.RelationshipCodeLookup.Add(relCode);
}
db.SaveChanges();
}
How do I update using Entity Framework? I'm passing in the object with the updated values, but I don't see an Update method.
public void UpdateRecipient(Domain.Entities.RecipientEntity recipient)
{
using (EfDbContext context = CreateEfDbContext(recipient.ApplicationId.ToString()))
{
context.Recipients. //?? I don't see an update method
context.SaveChanges();
}
}
Three steps:
Get the item to update from the context
Copy over the updated properties from the entity you pass your update method
Save the changes.
Roughly:
using (EfDbContext context = CreateEfDbContext(recipient.ApplicationId.ToString()))
{
var toUpdate = context.Recipients.SingleOrDefault(r => r.Id == recipient.Id);
if (toUpdate != null)
{
toUpdate.Field1 = recipient.Field1;
// Map over any other field data here.
context.SaveChanges();
}
else
{
// Handle this case however you see fit. Log an error, throw an error, etc...
}
}
There is another way of updating object without re-fetching it from the database again thus by saving cost of a trip to database. The object being attached must have a value for its primary key.
Attach the updated object to the context
Change it's state to 'modified'.
Call SaveChanges() method of the context
Like:
public void UpdateRecipient(Domain.Entities.RecipientEntity recipient)
{
using (EfDbContext context = CreateEfDbContext(recipient.ApplicationId.ToString()))
{
context.Attach(recipient);
context.ObjectStateManager.ChangeObjectState(recipient,EntityState.Modified);
context.SaveChanges();
}
}
If you're updating the record then you'd do something like this:
//Retrieve the entity to be updated
Entity row = context.Recipients.Single(a => a.Id == recipient.Id);
//Update a column
row.Name = recipient.Name;
//Save changes
context.SaveChanges();
If you want to update/add things at the same time then you'd do:
if(!context.Recipients.Any(a => Id == recipient.Id))
{
context.Recipients.Add(recipient);
}
else
{
Entity row = context.Recipients.Single(a => a.Id == recipient.Id);
row.Name = recipient.Name;
}
context.SaveChanges();