How Does the Entity Framework ChangeTracker know that a property has changed?












0















How does the Entity Framework ChangeTracker know that a property has changed? The properties have no advanced setter. I would like to know how to track those changes.










share|improve this question























  • It keeps internally a snapshot of the last retrieved/applied properties.

    – Ivan Stoev
    Nov 27 '18 at 9:48
















0















How does the Entity Framework ChangeTracker know that a property has changed? The properties have no advanced setter. I would like to know how to track those changes.










share|improve this question























  • It keeps internally a snapshot of the last retrieved/applied properties.

    – Ivan Stoev
    Nov 27 '18 at 9:48














0












0








0








How does the Entity Framework ChangeTracker know that a property has changed? The properties have no advanced setter. I would like to know how to track those changes.










share|improve this question














How does the Entity Framework ChangeTracker know that a property has changed? The properties have no advanced setter. I would like to know how to track those changes.







entity-framework change-tracking






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 9:09









Sascha SanfteilSascha Sanfteil

83




83













  • It keeps internally a snapshot of the last retrieved/applied properties.

    – Ivan Stoev
    Nov 27 '18 at 9:48



















  • It keeps internally a snapshot of the last retrieved/applied properties.

    – Ivan Stoev
    Nov 27 '18 at 9:48

















It keeps internally a snapshot of the last retrieved/applied properties.

– Ivan Stoev
Nov 27 '18 at 9:48





It keeps internally a snapshot of the last retrieved/applied properties.

– Ivan Stoev
Nov 27 '18 at 9:48












1 Answer
1






active

oldest

votes


















0














If you use the DbContext and DbSets normally, you won't add items to the change tracker. Before you can change any property of an entity, you'll first have to fetch it. Also if you want to delete it, you'll first have to fetch it.



The change tracker holds all fetched items, at least until SaveChanges, but probably until the DbContext is Disposed, if you really want to know, write some test code.



The ChangeTracker also holds all Added items.



The sequence of fetched and added items in the ChangeTracker can be accessed using method Entries or Entries<...>. The returned value is a sequence of DbEntityEntries. Every DbEntityEntry has a State, indicating whether it was Added / Deleted / Modified / Unchanged



After you fetched the item, its state is Unchanged. If you call Delete, the state changes in Deleted. If you add an object the State if Added. The difficult pare is Modified, because you can modify an item without using DbSet:



// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
.Where(school => school.Name = "J.F. Kennedy School")
.Select(school => school.Id)
.FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;


How does the ChangeTracker know you changed the SchoolId?



Luckily, the DbEntityEntry holds the original database values as well as the current values. So when you ask for the state, all it has to do is check if it has been added / deleted / etc. Most states are easy, only if it is Unchanged, the function that fetches the state will have to check all original values with all currentValues, using a default value comparer. If there are differences, the state is marked Changed, so the next time the value comparison is not needed.



You can't undo this: once the State is changed, you can't unchange it:



int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
.Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
.Select(studentEntity => studentEntity.State)
.SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:
state = ...
// state is still changed





share|improve this answer
























  • Good answer! Thank you.

    – Sascha Sanfteil
    Nov 27 '18 at 11:07











  • It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

    – Harald Coppoolse
    Nov 27 '18 at 11:11











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53496109%2fhow-does-the-entity-framework-changetracker-know-that-a-property-has-changed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














If you use the DbContext and DbSets normally, you won't add items to the change tracker. Before you can change any property of an entity, you'll first have to fetch it. Also if you want to delete it, you'll first have to fetch it.



The change tracker holds all fetched items, at least until SaveChanges, but probably until the DbContext is Disposed, if you really want to know, write some test code.



The ChangeTracker also holds all Added items.



The sequence of fetched and added items in the ChangeTracker can be accessed using method Entries or Entries<...>. The returned value is a sequence of DbEntityEntries. Every DbEntityEntry has a State, indicating whether it was Added / Deleted / Modified / Unchanged



After you fetched the item, its state is Unchanged. If you call Delete, the state changes in Deleted. If you add an object the State if Added. The difficult pare is Modified, because you can modify an item without using DbSet:



// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
.Where(school => school.Name = "J.F. Kennedy School")
.Select(school => school.Id)
.FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;


How does the ChangeTracker know you changed the SchoolId?



Luckily, the DbEntityEntry holds the original database values as well as the current values. So when you ask for the state, all it has to do is check if it has been added / deleted / etc. Most states are easy, only if it is Unchanged, the function that fetches the state will have to check all original values with all currentValues, using a default value comparer. If there are differences, the state is marked Changed, so the next time the value comparison is not needed.



You can't undo this: once the State is changed, you can't unchange it:



int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
.Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
.Select(studentEntity => studentEntity.State)
.SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:
state = ...
// state is still changed





share|improve this answer
























  • Good answer! Thank you.

    – Sascha Sanfteil
    Nov 27 '18 at 11:07











  • It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

    – Harald Coppoolse
    Nov 27 '18 at 11:11
















0














If you use the DbContext and DbSets normally, you won't add items to the change tracker. Before you can change any property of an entity, you'll first have to fetch it. Also if you want to delete it, you'll first have to fetch it.



The change tracker holds all fetched items, at least until SaveChanges, but probably until the DbContext is Disposed, if you really want to know, write some test code.



The ChangeTracker also holds all Added items.



The sequence of fetched and added items in the ChangeTracker can be accessed using method Entries or Entries<...>. The returned value is a sequence of DbEntityEntries. Every DbEntityEntry has a State, indicating whether it was Added / Deleted / Modified / Unchanged



After you fetched the item, its state is Unchanged. If you call Delete, the state changes in Deleted. If you add an object the State if Added. The difficult pare is Modified, because you can modify an item without using DbSet:



// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
.Where(school => school.Name = "J.F. Kennedy School")
.Select(school => school.Id)
.FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;


How does the ChangeTracker know you changed the SchoolId?



Luckily, the DbEntityEntry holds the original database values as well as the current values. So when you ask for the state, all it has to do is check if it has been added / deleted / etc. Most states are easy, only if it is Unchanged, the function that fetches the state will have to check all original values with all currentValues, using a default value comparer. If there are differences, the state is marked Changed, so the next time the value comparison is not needed.



You can't undo this: once the State is changed, you can't unchange it:



int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
.Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
.Select(studentEntity => studentEntity.State)
.SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:
state = ...
// state is still changed





share|improve this answer
























  • Good answer! Thank you.

    – Sascha Sanfteil
    Nov 27 '18 at 11:07











  • It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

    – Harald Coppoolse
    Nov 27 '18 at 11:11














0












0








0







If you use the DbContext and DbSets normally, you won't add items to the change tracker. Before you can change any property of an entity, you'll first have to fetch it. Also if you want to delete it, you'll first have to fetch it.



The change tracker holds all fetched items, at least until SaveChanges, but probably until the DbContext is Disposed, if you really want to know, write some test code.



The ChangeTracker also holds all Added items.



The sequence of fetched and added items in the ChangeTracker can be accessed using method Entries or Entries<...>. The returned value is a sequence of DbEntityEntries. Every DbEntityEntry has a State, indicating whether it was Added / Deleted / Modified / Unchanged



After you fetched the item, its state is Unchanged. If you call Delete, the state changes in Deleted. If you add an object the State if Added. The difficult pare is Modified, because you can modify an item without using DbSet:



// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
.Where(school => school.Name = "J.F. Kennedy School")
.Select(school => school.Id)
.FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;


How does the ChangeTracker know you changed the SchoolId?



Luckily, the DbEntityEntry holds the original database values as well as the current values. So when you ask for the state, all it has to do is check if it has been added / deleted / etc. Most states are easy, only if it is Unchanged, the function that fetches the state will have to check all original values with all currentValues, using a default value comparer. If there are differences, the state is marked Changed, so the next time the value comparison is not needed.



You can't undo this: once the State is changed, you can't unchange it:



int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
.Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
.Select(studentEntity => studentEntity.State)
.SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:
state = ...
// state is still changed





share|improve this answer













If you use the DbContext and DbSets normally, you won't add items to the change tracker. Before you can change any property of an entity, you'll first have to fetch it. Also if you want to delete it, you'll first have to fetch it.



The change tracker holds all fetched items, at least until SaveChanges, but probably until the DbContext is Disposed, if you really want to know, write some test code.



The ChangeTracker also holds all Added items.



The sequence of fetched and added items in the ChangeTracker can be accessed using method Entries or Entries<...>. The returned value is a sequence of DbEntityEntries. Every DbEntityEntry has a State, indicating whether it was Added / Deleted / Modified / Unchanged



After you fetched the item, its state is Unchanged. If you call Delete, the state changes in Deleted. If you add an object the State if Added. The difficult pare is Modified, because you can modify an item without using DbSet:



// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
.Where(school => school.Name = "J.F. Kennedy School")
.Select(school => school.Id)
.FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;


How does the ChangeTracker know you changed the SchoolId?



Luckily, the DbEntityEntry holds the original database values as well as the current values. So when you ask for the state, all it has to do is check if it has been added / deleted / etc. Most states are easy, only if it is Unchanged, the function that fetches the state will have to check all original values with all currentValues, using a default value comparer. If there are differences, the state is marked Changed, so the next time the value comparison is not needed.



You can't undo this: once the State is changed, you can't unchange it:



int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
.Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
.Select(studentEntity => studentEntity.State)
.SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:
state = ...
// state is still changed






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 27 '18 at 10:55









Harald CoppoolseHarald Coppoolse

12.6k12961




12.6k12961













  • Good answer! Thank you.

    – Sascha Sanfteil
    Nov 27 '18 at 11:07











  • It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

    – Harald Coppoolse
    Nov 27 '18 at 11:11



















  • Good answer! Thank you.

    – Sascha Sanfteil
    Nov 27 '18 at 11:07











  • It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

    – Harald Coppoolse
    Nov 27 '18 at 11:11

















Good answer! Thank you.

– Sascha Sanfteil
Nov 27 '18 at 11:07





Good answer! Thank you.

– Sascha Sanfteil
Nov 27 '18 at 11:07













It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

– Harald Coppoolse
Nov 27 '18 at 11:11





It becomes complicated once you start Attaching / Detaching items directly, instead of fetching an item. I see people to this regularly, but I think it is bad practice, especially if you keep in mind that several people might change your database.

– Harald Coppoolse
Nov 27 '18 at 11:11




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53496109%2fhow-does-the-entity-framework-changetracker-know-that-a-property-has-changed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)