Entity Framework Code First
Telerik Academy Alpha
Databases
Table of contents
Modeling Workflows
Modeling Workflows
-
Entity Framework supports three types of modeling workflow:
-
Database first
-
Create models as database tables
-
Use Management Studio or native SQL queries
-
-
Model first
-
Create models using visual EF designer in VS
-
-
Code first
-
Write models and combine them in DbContext
-
-
Database First
-
Create models as database tables and then generate code (models) from them
Model First
-
Create models as database diagrams and then generate code (models) and tables from them
Code First
-
Create models as code classes and then generate diagram and tables from them
Why use Code First?
-
Write code without having to define mappings in XML or create database models
-
Define objects in POCO
-
Reuse these models and their attributes
-
-
No base classes required
-
Enables database persistence with no configuration
-
Can use automatic migrations
-
-
Can use Data Annotations (Key, Required, etc.)
Code First
Data Models
-
Bunch of normal C# classes (POCO)
-
May contain navigation properties
-
public class PostAnswer
{
public int PostAnswerId { get; set; } // Primary key
public string Content { get; set; }
public int PostId { get; set; } // Foreign key
public virtual Post Post { get; set; } // Navigation property
}
Data Models
-
Another example of data class (model)
public class Post
{
private ICollection<PostAnswer> answers;
public Post()
{
this.answers = new HashSet<PostAnswer>();
}
public PostType Type { get; set; } // Enum, saved as an integer
public virtual ICollection<PostAnswer> Answers
{
get { return this.answers; }
set { this.answers = value; }
}
}
public class Post
{
public Post()
{
this.Answers = new HashSet<PostAnswer>();
}
public PostType Type { get; set; } // Enum, saved as an integer
public virtual ICollection<PostAnswer> Answers { get; set; }
}
DbContext
-
A class that inherits from DbContext
-
Manages model classes using DbSet type
-
Implements identity tracking, change tracking, and API for CRUD operations
-
Provides LINQ-based data access
-
-
Recommended to be in a separate class library
-
Don't forget to reference the Entity Framework library (using NuGet package manager)
-
-
If you have a lot of models it is recommended to use more than one DbContext
DbSet
-
Collection of single entity type
-
Set operations: Add, Attach, Remove, Find
-
Use with DbContext to query database
public DbSet<Post> Posts { get; set; }
public DbSet<PostAnswer> PostAnswers { get; set; }
DbContext Example
using System.Data.Entity;
using CodeFirst.Models;
public class ForumContext : DbContext
{
public IDbSet<Post> Posts { get; set; }
public IDbSet<PostAnswer> PostAnswers { get; set; }
public IDbSet<Category> Categories { get; set; }
public IDbSet<Tag> Tags { get; set; }
}
Data Interaction Example
var db = new ForumContext();
var category = new Category { Parent = null, Name = "Database course" };
db.Categories.Add(category);
var post = new Post();
post.Title = "Срока на домашните";
post.Content = "Моля удължете срока на домашните";
post.Type = PostType.Normal;
post.Category = category;
post.Tags.Add(new Tag { Text = "домашни" });
post.Tags.Add(new Tag { Text = "срок" });
db.Posts.Add(post);
db.SaveChanges();
How to connect to SQL Server?
-
First, create context constructor that calls base constructor with appropriate connection name
public class ForumContext : DbContext
{
public ForumContext()
: base("ForumDb")
{ }
// ...
}
-
Then add the connection string in app.config
<connectionStrings>
<add name="ForumDb" connectionString="Data Source=.;Initial
Catalog=ForumDb;Integrated Security=True"
providerName="System.Data.SqlClient" ></add>
</connectionStrings>
Code First Migrations
Migrations
-
What happens when we change our models?
-
Entity Framework compares our model with the model in __MigrationHistory table
-
By default Entity Framework only creates the database and don't do any changes after that
-
Using Code First Migrations we can manage differences between models and database
-
Migrations
-
Enable Code First Migrations
-
Open Package Manager Console
-
Run Enable-Migrations command
-
This will create some initial jumpstart code
-
-
Two types of migrations
-
Automatic migrations
-
Set AutomaticMigrationsEnabled = true;
-
Development ONLY!
-
-
-
Code-based (providing full control)
-
Separate C# code file for every migration
-
-
-
Migration Strategies
-
CreateDatabaseIfNotExists (default)
-
DropCreateDatabaseIfModelChanges
-
We loose all the data when change the model
-
-
DropCreateDatabaseAlways
-
Great for automated integration testing
-
-
MigrateDatabaseToLatestVersion
-
This option uses our migrations
-
-
We can implement IDatabaseInitializer if we want custom migration strategy
How to use?
-
First, enable code first migrations
-
Second, we need to tell to Entity Framework to use our migrations with code (or app.config)
-
Database.SetInitializer(
new MigrateDatabaseToLatestVersion<ForumContext, Configuration>());
-
We can configure automatic migration
public Configuration()
{
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
}
Seed database
-
During a migration we can seed the database with some data using the Seed method
-
This method will be run every time (since EF 5)
-
Only for testing purposes
-
protected override void Seed(ForumContext context)
{
/* This method will be called after migrating to
the latest version. You can use the
DbSet.AddOrUpdate() helper extension method
to avoid creating duplicate seed data. E.g. */
context.Tags.AddOrUpdate(new Tag { Text = "срок" });
context.Tags.AddOrUpdate(new Tag { Text = "форум" });
}
Configure Mappings
Migrations
-
Entity Framework respects mapping details from two sources
-
Data annotation attributes in the models
-
Can be reused for validation purposes
-
-
Fluent API code mapping configuration
-
By overriding OnModelCreating method
-
By using custom configuration classes
-
-
Use one approach or the other
-
Mappings
-
There is a bunch of data annotation attributes in System.ComponentModel.DataAnnotations
-
[Key] – specifies the primary key of the table
-
For validation: [StringLength], [MaxLength], [MinLength], [Required]
-
Schema: [Column], [Table], [ComplexType], [ConcurrencyCheck], [Timestamp], [ComplexType], [InverseProperty], [ForeignKey], [DatabaseGenerated], [NotMapped], [Index]
-
-
In EF 6 we are able to add custom attributes by using custom conventions
Fluent API
-
By overriding OnModelCreating method in DbContext class we can specify mapping configurations
protected override void OnModelCreating(
DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().HasKey(x => x.Id);
modelBuilder.Entity<student>().Property(x => x.Name)
.IsUnicode(true);
modelBuilder.Entity<Student>().Property(x => x.Text)
.HasMaxLength(255);
base.OnModelCreating(modelBuilder);
}
Fluent API
-
.Entity()
-
Map: Table Name, Schema
-
Inheritance Hierarchies, Complex Types
-
Entity -> Multiple Tables
-
Table -> Multiple Entities
-
Specify Key (including Composite Keys)
-
Fluent API
-
.Property()
-
Attributes (and Validation)
-
Map: Column Name, Type, Order
-
Relationships
-
Concurrency
-
context.Questions.ToList();
[Databases] Entity Framework Code First
By telerikacademy
[Databases] Entity Framework Code First
- 1,452