Verify If Entity Was Modified In Entity Framework Code First - entity-framework

Is there an easy way to verify if an entity was updated instead of keeping tracket of a flag when testing if some properties have changed on a code first entity framework entity?
bool hasChanges = false;
if (existingEvent.Gender != tournament.Gender)
{
hasChanges = true;
existingEvent.Gender = tournament.Gender;
}

I found out I can do it like this.
DatabaseFactory.Get().Entry(existingEvent).State

Related

Make Configuration changes to DbContext

I'm using Code First. I've created a DbContext but I'm not able to put the configuration settings in the constructor as I did in the regular Entity Framework. Here's an example in regular EF6:
public AppsDbContext()
: base("name=AppsDbContext")
{
this.Configuration.AutoDetectChangesEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.UseDatabaseNullSemantics = true;
this.Configuration.ValidateOnSaveEnabled = false;
}
I'm not able to do this in an EF-Core DbContext constructor. What I noticed immediately is that I got this functionality from the System.Data.Entity namespace in EF, which apparently no longer exists. I do not see a way I can add this namespace. What am I missing? I'm guessing this is fairly trivial but I have not seen any examples in my search.
NOTE: I'm using EF Core 2.2
you can use ChangeTracker property instead of Configuration in EF-Core.
this.ChangeTracker.LazyLoadingEnabled = true;
this.ChangeTracker.AutoDetectChangesEnabled = false;

Entity Framework: partially update record not working

I have the following set up:
All instances are injected, UnitOfWork and DataContext are singletons.
I want to do a partial update of a record.
In the generic repository, I have the following code in my update statement:
dbSet.Attach(entity);
if (updatedProperties != null)
{
foreach (var property in updatedProperties)
{
unitOfWork.DataContext.Entry<TEntity>(entity).Property(property).IsModified = true;
}
}
In my update method, I accept a List of string with the updated fields.
This method is called from the usermanager with the following code:
userRepo.Update(origUser, updatedProperties);
if(processToDB)
{
unitOfWork.SaveChanges();
}
The variable processToDB is set to true. I step into the code, I see in the changetracker that the entity is there, but the update never happens.
So, what fixes this for me, but I don't find this a good fix, is calling the SaveChanges method directly from the Update method in the generic repository:
dbSet.Attach(entity);
if (updatedProperties != null)
{
foreach (var property in updatedProperties)
{
unitOfWork.DataContext.Entry<TEntity>(entity).Property(property).IsModified = true;
}
unitOfWork.SaveChanges(); //added
}
Why doesn't it work when calling the savechanges on the user manager, it is after all the samen unitOfWork and DataContext (because they are singletons).
You don't need to set IsModified for each entity properties. Use AutoDetectChangesEnabled property and set as true while initialize your EF model as
DbContext.Configuration.AutoDetectChangesEnabled = true;
It will make EF to track changes on your entity object. You may check it by using
unitOfWork.DataContext(entity).State == EntityState.Modifed.
If the above condition get paced then update your entity.

Entity Framework Include method

when i try to use include i can't access to table context.Users, only to it's fields
Where is my mistake?
Thanks.
Using the Load method means you are some how trying to use Eager loading of certain requirements, what you could try and do is turn off Lazy Loading, this way all queries will load related entities without having to use the Include Method. They proxy entities will handle the references between the entity relationships for you.
Once you return Doctors in your View, and you loop through them
foreach(var doctor in Model) { #doctor.PhoneNumber.EmergencyNumber }
PhoneNumber will be proxied by EF and you will not need to use any Eager Loading through the Include function.
public Context() : base("DefaultConnection")
{
Configuration.ProxyCreationEnabled = true; // Our Navigational Properties
Configuration.LazyLoadingEnabled = false; // No need to Include with Eager Loading
Configuration.AutoDetectChangesEnabled = true; // Change Tracker for changes made on either side of the Association through Proxy Class
Configuration.ValidateOnSaveEnabled = true; // Validate On Saving for Data Integrity
}
you should use context.Doctor.Include(d=>d.PhoneNumbers)
this will extract all doctors with filled phone numbers per each

How to update only modified values (EntityFramework 5.0)?

I have this entity, want to update using entityframework
EmployeeModel employee = new EmployeeModel
{
Id = 1000, //This one must
FirstName = modifiedValue,
Email = modifiedValue,
LastName = originalValue,
Phone = originalValue
};
Code to update
_db.ObjectStateManager.ChangeObjectState(employee, EntityState.Modified);
_db.SaveChanges();
This is the SQL statement got once updated
Update Employee set Id=1138,FirstName='modifiedValue',Email='modifiedValue',LastName= 'OriginalValue',phone='originalValue' where Id=1138
But I am expecting this
Update Employee set FirstName='modifiedValue', Email='modifiedValue' where Id=1138.
I dont know what I am missing here. Please let me know.
This problem is common when dealing with DTOs. An employee entity is fetched from the database, mapped to a DTO and sent over the wire. The client then modifies this DTO and sends it back to the server.
When you touch (set) a property on an EF entity, EF will assume that the value has been changed. Even if the old value and the new value are exactly the same.
The same problem occurs when you map the DTO to a new Entity and attach it to EF and updating its status to 'Modified'.
Using AutoMapper:
// This will result in the full update statement
var employee = AutoMapper.Mapper.Map<EmployeeDto, Employee>(dto);
// This will result in a smaller update statement (only actual changes)
var employee = dbContext.Employees.Find(dto.Id);
AutoMapper.Mapper.Map(dto, employee);
Or, manually (I would avoid doing this, but just for the sake of completeness):
// This will result in a smaller update statement (only actual changes)
var employee = dbContext.Employees.Find(dto.Id);
if (employee.Email != dto.Email )
employee.Email = dto.Email;
There are probably some other ways for dealing with this problem... but using AutoMapper together with Entity Framework correctly is definitely one of the easiest ways.
This is the solution I got
var entity = _db.CreateObjectSet<Employee>();
entity.Detach(employee);
entity.Attach(employee);
foreach (string modifiedPro in employeeModel.ModifiedProperties){
_db.ObjectStateManager.GetObjectStateEntry(employee).SetModifiedProperty(modifiedPro);}
_db.SaveChanges();
Only modified values in the sql update statement
Update Employee set FirstName='modifiedValue', Email='modifiedValue' where Id=1138.
If anybody knows better answer than this, Please post your suggestions
You can try this way
public update(Person model)
{
// Here model is model return from form on post
var oldobj = db.Person.where(x=>x.ID = model.ID).SingleOrDefault();
var UpdatedObj = (Person) Entity.CheckUpdateObject(oldobj, model);
db.Entry(oldobj).CurrentValues.SetValues(UpdatedObj);
}
public static object CheckUpdateObject(object originalObj, object updateObj)
{
foreach (var property in updateObj.GetType().GetProperties())
{
if (property.GetValue(updateObj, null) == null)
{
property.SetValue(updateObj,originalObj.GetType().GetProperty(property.Name)
.GetValue(originalObj, null));
}
}
return updateObj;
}

Entity Framework Update - Overwrite values or not

I am using Entity Framework 4.1 to perform CRUD operations against my database. I have turned off the following properties:
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.AutoDetectChangesEnabled = false;
My method to update a user object
public void Edit(User user)
{
_context.Entry(user).State = System.Data.EntityState.Modified;
_context.SaveChanges();
}
Ive retrieved:
User.Forename = Joe
User.Surname = Bloggs
Ive passed the user object to my edit method with
User.Forename = Joe
User.Surname = Bloggs
If I pass my user object to my Edit method but i haven't changed any of its properties, as above. Will the properties be over written in the database with the same value or will Entity Framework know the value hasn't changed?
Since you explicitly set the state to Modified, EF does send an update statement to the database even if none of the property values have changed.
If you don't want EF to update the database with the same values, you'll have to add logic to track whether the values have changed since you are setting AutoDetectChangesEnabled to false.