Exclude Property on Update in Entity Framework
we can use like this
db.Entry(model).State = EntityState.Modified;
db.Entry(model).Property(x => x.Token).IsModified = false;
db.SaveChanges();
it will update but without Token property
Exclude property from updating when SaveChanges() is called
The following may work works.
myDbContext.Dogs.Attach(dog);
myDbContext.Entry(dog).State = EntityState.Modified;
var objectContext = ((IObjectContextAdapter) myDbContext).ObjectContext;
foreach (var entry in objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified).Where(entity => entity.Entity.GetType() == typeof(Dogs)))
{
// You need to give Foreign Key Property name
// instead of Navigation Property name
entry.RejectPropertyChanges("OwnerID");
}
myDbContext.SaveChanges();
If you want to do it in a single line, use the following extension method:
public static void DontUpdateProperty<TEntity>(this DbContext context, string propertyName)
{
var objectContext = ((IObjectContextAdapter) context).ObjectContext;
foreach (var entry in objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified).Where(entity => entity.Entity.GetType() == typeof(TEntity)))
{
entry.RejectPropertyChanges(propertyName);
}
}
And use it like this
// After you modify some POCOs
myDbContext.DontUpdateProperty<Dogs>("OwnerID");
myDbContext.SaveChanges();
As you can see, you can modify this solution to fit your needs, e.g. use string[] properties
instead of string propertyName
as the argument.
Suggested Approach
A better solution would be to use an Attribute as you suggested ([NeverUpdate]). To make it work, you need to use SavingChanges event (check my blog):
void ObjectContext_SavingChanges(object sender, System.Data.Objects.SavingChangesEventArgs e)
{
ObjectContext context = sender as ObjectContext;
if(context != null)
{
foreach(ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
{
var type = typeof(entry.Entity);
var properties = type.GetProperties();
foreach( var property in properties )
{
var attributes = property.GetCustomAttributes(typeof(NeverUpdateAttribute), false);
if(attributes.Length > 0)
entry.RejectPropertyChanges(property.Name);
}
}
}
}
// Check Microsoft documentation on how to create custom attributes:
// http://msdn.microsoft.com/en-us/library/sw480ze8(v=vs.80).aspx
public class NeverUpdateAttribute: SystemAttribute
{
}
//In your POCO
public class Dogs
{
[NeverUpdate]
public int OwnerID { get; set; }
}
Warning: I did not compile this code. I'm not at home :/
Warning 2: I have just read the MSDN documentation and it says:
ObjectStateEntry.RejectPropertyChanges Method
Rejects any changes made to the property with the given name since the
property was last loaded, attached, saved, or changes were accepted.
The orginal value of the property is stored and the property will no
longer be marked as modified.
I am not sure what its behavior would be in the case of attaching a modified entity. I will try this tomorrow.
Warning 3: I have tried it now. This solution works. Property that is rejected with RejectPropertyChanges()
method are not updated in the persistence unit (database).
HOWEVER, if the entity that is updated is attached by calling Attach()
, the current context remains dirty after SaveChanges()
. Assume that the following row exists in the database:
Dogs
ID: 1
Name: Max
OwnerID: 1
Consider the following code:
var myDog = new Dogs();
myDog.ID = 1;
myDog.Name = Achilles;
myDog.OwnerID = 2;
myDbContext.Dogs.Attach(myDog);
myDbContext.Entry(myDog).State = EntityState.Modified;
myDbContext.SaveChanges();
The current state of database after SaveChanges():
Dogs:
ID: 1
Name: Achilles
OwnerID: 1
The current state of myDbContext after SaveChanges():
var ownerId = myDog.OwnerID; // it is 2
var status = myDbContext.Entry(myDog).State; // it is Unchanged
So what you should do? Detach it after SaveChanges():
Dogs myDog = new Dogs();
//Set properties
...
myDbContext.Dogs.Attach(myDog);
myDbContext.Entry(myDog).State = EntityState.Modified;
myDbContext.SaveChanges();
myDbContext.Entry(myDog).State = EntityState.Detached;
How to ignore properties in Entity Framework 6 for Update?
If you are trying to ignore properties in an entity, then you would need to add a [NotMapped] attribute to that property in the class. More documentation here: https://learn.microsoft.com/en-us/ef/core/modeling/included-properties
Also, it seems like the error presented is more to do with you attempting modify a Primary key or index. I see this is actually answered here: https://stackoverflow.com/a/12397981/1670574
Ignore one property on update Entity Framework
Personally, I use AutoMapper and use Ignore on the one field you don't want to copy. This way, if you ever add new columns to the table, you don't have to worry about adding them to your repository.
So, something like this...
void UpdatePerson(Person p) {
var person = db.Persons.Find(PersonId);
Mapper.CreateMap<Person, Person>()
.ForMember(dest => dest.CreationDate, opt => opt.Ignore());
Mapper.Map(p, person);
db.SaveChanges();
}
Update an entity using entity framework while ignoring some properties
If your using EF 5, you can mark a property as not modified after its been marked as modified
_db.Entry(candidat).State = EntityState.Modified;
// Ignore changes to the value of SomeProperty
_db.Entry(candidat).Property("SomeProperty").IsModified = false;
_db.SaveChanges();
EntityFramework Exclude Some Fields in Updating and Inserting
Insert
Use [DatabaseGenerated(DatabaseGeneratedOption.Computed)] data annotation on DateCreated column to use default value generated by the database.
https://msdn.microsoft.com/en-us/data/jj591583.aspx#DatabaseGenerated
Update
Entity Framework only update modified field, so simply don't change the value of UserCreated and it will not be updated.
EF Core: Ignore property only on save
You have to set both BeforeSaveBehavior
(for insert) and AfterSaveBehavior
(for update) of the entity property to Ignore
.
Currently there is no fluent API for that, but you could use the metadata API, e.g.
modelBuilder.Entity<Blog>().Property(e => e.ViewProp1)
.Metadata.SetBeforeSaveBehavior(PropertySaveBehavior.Ignore);
modelBuilder.Entity<Blog>().Property(e => e.ViewProp1)
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
Related Topics
Call Non-Static Method in Server-Side from Client-Side Using Javsscript
The Entity Type Applicationuser Is Not Part of the Model for the Current Context
Convert Binary String into Integer
Resolve Assembly References from Another Folder
Azure Ad B2C - Role Management
How to Prevent a SQL Injection Escaping Strings
Why Doesn't Xmlserializer Support Dictionary
How to Make the Value of a Variable Track the Value of Another
How to Get the Full Url of the Page I am on in C#
Httpclient Not Supporting Postasjsonasync Method C#
What's the Correct Alternative to Static Method Inheritance
Pattern for Calling Wcf Service Using Async/Await
How to Convert Datetime To/From Specific String Format (Both Ways, E.G. Given Format Is "Yyyymmdd")
Should I Use Two "Where" Clauses or "&&" in My Linq Query