How to check if all the key properties of an entity object contain valid values in EF Core?
In the web application, all the entities that come to data layer will be disconnected entities. It means that they are not being tracked by the DbContext. So, to decide whether to add or update entities, you should check their key properties. If the key property contains the default value of the data type (for example, 0 for int type property) then it will be treated as a new entity which needs to be added, and if the key property contains non-default value then it will be treated as an existing entity which needs to be updated.
EF Core provides the IsKeySet property of the EntityEntry<TEntity>
class
that checks whether the keys of an entity are set or not. The IsKeySet returns true if all the key properties of an entity contain valid values otherwise returns false.
Consider the following example.
//disconnected entities var std1 = new Student() { StudentName = "Steve" }; // new entity var std2 = new Student() { StudentID = 1, StudentName = "Bill" };//updated entity using (var context = new SchoolContext()) { Console.WriteLine( context.Entry<Student>(std1).IsKeySet); // false, no valid value Console.WriteLine( context.Entry<Student>(std2).IsKeySet); //true, valid value }
In the above example, consider std1
and std2
as disconnected entities. Std1
does not have StudentID
whereas std2
includes a valid value for StudentID
.
So, context.Entry<Student>(std1).IsKeySet
returns false because it does not have valid StudentID
, and context.Entry<Student>(std2).IsKeySet
returns true because it contains valid value for StudentID
.
The IsKeySet behaves the same even if an entity includes multiple key properties (composite keys) . Thus, no need to check individual key properties manually.
This is useful in deciding whether to add or update a disconnected entity, as shown below.
var std = new Student(){ StudentName="Bill" }; using (var context = new SchoolContext()) { if( context.Entry<Student>(std).IsKeySet) // false means add entity { context.Add(std); } else { context.Update(std); } }