06 - Entity Framework
Logging
Add simple logging, to see generated SQL statements on console.
Nuget install Microsoft.Extensions.Logging.Console
Define LoggerFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Migrations
Console command line
1 2 3 |
|
From code
1 |
|
Data access
Eager, Explicit, Lazy
Eager – load all data at once
Explicit – load data, when needed
Lazy – load data automatically when accessing navigation property, without doing specific db operations
Lazy - not recommended. 1+N query problem.
Eager
Eager – specify data to include in query results (SQL JOIN)
1 |
|
Eager – include several relationships
1 2 |
|
Eager – include multiple levels
1 2 |
|
Primary Key
Use conventions!
<ClassName>Id
or just Id
Annotations
[Key]
Fluent API
1 2 |
|
Composite key – only in Fluent
1 2 |
|
Required/Optional
If property is nullable – by convention not required
Annotations
[Required]
Fluent API
1 2 |
|
Maximum length
- By convention depends on the provider
- Annotation
[MaxLength(<Length>)]
- Fluent API
modelBuilder.Entity<ModelClass>().Property(b => b.SomeProperty).HasMaxLength(<Length>);
Indexes
-
Index is created for every foreign key
-
Annotations
On top of entity class
[Index(nameof(Title), IsUnique = true)]
[Index(nameof(FirstName), nameof(LastName), IsUnique = true)]
- Fluent API
- Single property, non-unique
modelBuilder.Entity<ModelClass>().HasIndex(b => b.SomeProperty)
- Unique
modelBuilder.Entity<ModelClass>().HasIndex(b => b. SomeProperty) .IsUnique();
- More than one property
modelBuilder.Entity<ModelClass>().HasIndex( p => new { p. * SomeProperty1, p. SomeProperty2 });
- Single property, non-unique
Default value
Danger
Fluent API only!
modelBuilder.Entity<ModelClass>().Property(b => b.SomeNumber).HasDefaultValue(3);
modelBuilder.Entity<ModelClass>().Property(b => b.SqlProperty).HasDefaultValueSql("getdate()");
Exclude properties
- You can exclude types or properties from DB
- Annotations
[NotMapped]
- Fluent API (in dbcontext.OnModelCreating)
modelBuilder.Ignore<ModelClass>(); modelBuilder.Entity<ModelCalss>().Ignore(b => b.ModelProperty);
- Getter only properties are excluded automatically
Relationships
- If possible, use fully defined relationships.
- Navigation property defined on both ends, FK defined in dependent entity
- If there is only one relationship between two entities, EF will set up relationship automatically
- Some configuration is needed on other cases
- Data annotations
[ForeignKey]
[InverseProperty]
Foreign Key
[ForeignKey]
– when FK is not discovered.
[ForeignKey(nameof(Post.BlogForeignKey))]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Inverse Property
[InverseProperty]
- Used, when there are more than one relationships defined between two entities
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 |
|
Fluent API
- To configure a relationship in the Fluent API, you start by identifying the navigation properties that make up the relationship.
HasOne
orHasMany
identifies the navigation property on the entity type you are beginning the configuration on. You then chain a call toWithOne
orWithMany
to identify the inverse navigation.
1 2 3 4 5 6 |
|
Cascade delete
Tip
Cascade delete is automatically configured.
The default EF Core convention is to use DeleteBehavior.Cascade
for required and DeleteBehavior.ClientSetNull
for optional relationships.
You can turn of cascade delete for all entities (in DbContext):
1 2 3 4 5 6 7 8 9 10 11 |
|
Preexisting DB
Command prompt
1 2 3 4 5 6 7 8 |
|