关于导航属性
Figure 9.2 The examples that follow use these entity classes. OneEntity
is an optional, one-to-one relationship, because the foreign key back to MyEntity
is nullable. OneEntity
can exist in the database without being linked to MyEntity
(its foreign key will be null). The ManyEntity
entity class provides the Add
command—creating a new entity/row in the database
关于状态
Figure 9.1 The code on the left uses all the standard ways of creating, updating, and deleting data in a database. The middle column, Entity State, shows the EF Core State of the entity as it moves through each of these stages.
添加导航属性
Figure 9.3 Adding an entity with both an is tracked and a not tracked relationship. The is tracked case is shown in step 2: a tracked OneEntity
instance is set to Modified
because a foreign key in that entity was set. The not tracked case is shown in step 3: a new ManyEntity
entity instance is added to the myEntity
’s entity instance Many
collection navigational property.
Table 9.1 Examples of using the Add method, with and without relationships
EF Core code |
Entity’s state |
IsModified == true |
var entity = new MyEntity(); |
|
|
var entity = new MyEntity(); |
|
|
var entity = new MyEntity(); |
|
See Note a |
关于实体跟踪
Figure 9.5 The default way that EF Core finds whether anything has been changed. EF Core holds a tracking snapshot of any entities loaded as tracked entities—any query that doesn’t include the AsNoTracking
method. When SaveChanges
is called, EF Core, by default, runs the DetectChanges
method, which compares tracked entities with the tracking snapshot and sets the State
of the entities that have been modified to Modified
.
Table 9.3 Examples of modifying an entity, with and without relationships
EF Core code |
Entity’s state |
IsModified == true |
var entity = |
|
|
var entity = |
|
|
var entity = |
|
|
关于实体属性修改的事件,但是不建议使用
Listing 9.1 NotifyEntity
entity class, using NotificationEntity
class for events
public class NotifyEntity : NotificationEntity
{
private int _id; // private string _myString; // private NotifyOne _oneToOne; // public int Id { get => _id; set => SetWithNotify(value, ref _id); // } public string MyString { get => _myString; set => SetWithNotify(value, ref _myString); // } public NotifyOne OneToOne { get => _oneToOne; set => SetWithNotify(value, ref _oneToOne); // } public ICollection<NotifyMany> Collection { get; } // = new ObservableHashSet<NotifyMany>(); // }
public class NotificationEntity : INotifyPropertyChanged
{ public event PropertyChangedEventHandler PropertyChanged; protected void SetWithNotify<T>(T value, ref T field, [CallerMemberName] string propertyName = "")
// { if (!Object.Equals(field, value)) // { field = value; // PropertyChanged?.Invoke(this, // new PropertyChangedEventArgs(propertyName)); // } } }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{ modelBuilder .Entity<NotifyEntity>() .HasChangeTrackingStrategy( ChangeTrackingStrategy.ChangedNotifications); }
modelBuilder .HasChangeTrackingStrategy( ChangeTrackingStrategy.ChangedNotifications);