ISM 6225
Distributed
Information Systems
LEC T UR E 4 – E N T ITY F R AME WORK
BA S E D ON JUL I A L E R M AN,CHS 1 - 8
Agenda
• Background – domain models
• Code first components
• Entity framework example
• Loose ends
◦ Constraints - Fluent API and Data Annotations
◦ Connection strings - Database selection
◦ Migrations
◦ LINQ
• Entity Framework in MVC
2
Object-relational mapping
• Entity Framework
◦ Minimize SQL
◦ All SQL relations can be represented
◦ 0 to many
◦ 1 to many
◦ Many to many
◦ Type-checking
◦ Fewer run-time errors
◦ Downloaded from NuGet repository
3
Code first
• Developers create classes
◦ E.g. Person, Course etc
◦ Hence the name code first
◦ As opposed to database first
• Entity Framework builds and updates the SQL database with this
information
4
Code first components
1. POCO classes
◦ Plain old C# objects
◦ Name analogous to POJO
◦ Plain old java objects
◦ Or, POTS
◦ Plain old Telephone system
◦ No signs of Entity Framework
◦ But EF can draw many inferences from structure
◦ Convention over configuration
2. Entity Configuration
◦ Data annotations or Fluent
3. Application
◦ Uses POCO classes and entity configuration
5
Resources
• Based on personal experience
◦ Julia Lerman and Rowan Miller, “Programming Entity Framework: Code
first,” O’Reilly Media, ISBN 978-1449312947
◦ Fast-paced, technically-sound introduction
◦ Should know cover-to-cover
◦ Stack Overflow
◦ Professionally courteous responses to advanced questions
◦ Links to relevant resources – blogs etc
6
Technology evolution
EF Core 2
Aug 14, 2017
EF Core 1
Cross-platform, NoSQL, Jun ’16
EF 6 Used in
Last Windows exclusive release, Oct 2013 EdvisionApp
[Link]
(introduced in EF 4.1, ~2011)
[Link]
(Introduced with .NET 3.5, ~2007)
Dot net class library
Initial release ~ 2002
7
Using Entity Framework
• We will learn by example, starting with a simple MVC application
• For those interested
◦ Highly recommended: Simple Vet office, as in Julia Lerman book
• Learnings
◦ Installing Entity Framework
◦ Architecting use of Entity Framework
◦ Connecting to the database
◦ Configuring entities
8
Entity framework use
• Consider the typical application
Stock Application { SportsStore Application {
… <business logic> … <business logic>
Create/ Read/ Update/ Delete Patient records Create/ Read/ Update/ Delete Shopping carts
… <business logic> … <business logic>
} }
Companies Users
Quotes Products
Employees Vendors
Vets SportsStore
database database
9
Typical data architecture
Entities
Application { Used in
… <business logic>
Class Comapny(Id, Name, …)
CreateCompany(Id = 1) Class Quote(Id, Date, …)
ReadQuote(Id = 1) Related Class Employee(Id, Name, …)
… <business logic> DBContext : EntityFramework …
} in
Company(Id, Name, …)
Quote(Id, Date, …)
Employee(Id, Name, …)
…
Persisted
in
Companies
Quotes
Employees
Vets
database
10
Example setup
• We will map our solution to the data architecture
File name ORM function
EF_Models.cs Entity definitions
[Link] Entity framework context
[Link] Business application
[Link] Database connection
[Link] Connection string
11
Example setup
Application { Used in Entities
… <business logic>
CreateCompany(Id = 1) ApplicationDbContext Class Company(Id, Name, …)
ReadQuote(Id = 1) Class Quote(Id, Date, …)
Related
… <business logic> ApplicationDbContext : DbContext …
in
}
DbSet<Company> Companies EF_Models
HomeController DbSet<Equity> Equities
…
Persisted
in
Companies
Equities
Vets
database
12
Github project
• [Link]
13
Additions to MVC start project
• Company and Equity POCO classes added to Models
• [Link] added to the project
◦ Conventionally, in a folder named DataAccess
• Added [Link] to specify connection strings
"Data": {
"IEXTrading": {
"ConnectionString":
"Server=(localdb)\\MSSQLLocalDB;Database=IEXTrading;Trusted_Connection=True;Multipl
eActiveResultSets=true"
}
}
• Updated [Link] to configure EF with specified information
14
EntityFramework in action
• We have done a lot of little things, what should happen if all goes
well?
◦ The database should be created on local SQL Server instance
• Run solution
• Open SQL Server Object Explorer
◦ Personal opinion: One factor behind Microsoft’s success among developers
is their attention to detail in making things work easily
◦ Welcoming to newbies
• We can now build our database driven application
15
Results
• Out of the box, EF
worked with the
default database
setup in Visual Studio
• Use View → SQL
Server Object
Explorer to find it
◦ May need to use
“Add SQL Server” to
locate the database
• EF created and
populated the
database as specified
in our connection
string
16
Basic EntityFramework
conventions
• View the tables in SQL Server object
explorer
◦ Id column automatically identified as the
primary key
◦ AnimalType_Id added as a foreign key
◦ How did these happen?
◦ EntityFramework code first
• Remember?
◦ Convention over configuration
• Also, check out the data in the
_MigrationHistory table
◦ Very useful as your application evolves
17
EntityFramework conventions
• Class names are singular
◦ E.g. Person
• Table names are in plural
◦ E.g. People
◦ Using Entity Framework’s pluralization service
◦ Usually, appends s to class names
◦ E.g. State → States
• Columns have same names as class properties
18
EF conventions (contd.)
• Primary key
◦ Id field, or
◦ <class name>Id field
• One to many relationships
◦ Foreign key for A in class B
◦ List<B> in class A
◦ A in class B
◦ Slightly different implementation in Visit
◦ int PatientId
◦ EF detected intended foreign key relationship and named property accordingly
◦ But see next slide and listing 4-2 for recommended practice
19
Recommended model for
foreign key relationship
• See example 4-2 in JL
• Preferred model for Visit class would be:
public class Visit
{
public int Id { get; set; }
public DateTime Date { get; set; }
public String ReasonForVisit { get; set; }
public String Outcome { get; set; }
public Decimal Weight { get; set; }
//public int PatientId { get; set; }
public Patient Patient { get; set; }
}
20
Using the DbContext
• Database connectivity and EF integration with MVC has evolved over
time
◦ Earlier Ninject plugin was used
◦ Then OWIN framework was created
◦ With MVC core, database connectivity using EF appears to be a native
component of the framework
• We will see all CRUD operations in this simple example
• MVC uses dependency injection to use the EF context
◦ Update the HomeController as follows
◦ Makes database connection available to all methods in the controller
21
Using the DbContext
public class HomeController : Controller
{
public ApplicationDbContext dbContext;
public HomeController(ApplicationDbContext context)
{
dbContext = context;
}
…
}
22
Creating rows
• Create Company and related Equity classes in HomeController/Index
Company MyCompany = new Company();
[Link] = "ISM6225";
[Link] = "ISM";
…
Equity MyCompanyQuote1 = new Equity();
//[Link] = 123;
[Link] = "11-23-2018";
[Link] = 46.13F;
…
[Link] = "ISM6225";
23
Creating rows (contd.)
• [Link](MyCompany);
• [Link](MyCompanyQuote1);
• [Link](MyCompanyQuote2);
• [Link]();
24
Reading rows
• Include the following in the Index() method
◦ V. Important: Add a break point after the first line
◦ Watch the Equities collection in the first Company object after each line is executed
Company CompanyRead1 = [Link]
.Where(c => [Link] == "ISM6225")
.First();
Company CompanyRead2 = [Link]
.Include(c => [Link])
.Where(c => [Link] == "ISM6225")
.First();
25
Updating rows
• Entity Framework maintains the connection of retrieved entities with
the database
◦ Makes database operations fairly straightforward
[Link] = "MCOB";
[Link](CompanyRead1);
[Link]();
26
Deleting rows
[Link](CompanyRead1);
[Link]();
27
Progress so far
• Previous presentation covered basic MVC application components
• This presentation covered basic database connectivity
◦ And CRUD operations
◦ Using Entity Framework
• We now have the basic setup for database connectivity in place
◦ Can create data models of arbitrary complexity
◦ Use in application, and
◦ Persist in the database
28
Loose ends in database use
• Specifying constraints
◦ How do you specify more complex constraints?
◦ E.g. required fields
• Connection strings
◦ How do you connect to databases in non-default locations?
◦ E.g. AWS, Azure
• Migrations
◦ How do you gracefully change the data model?
◦ Not just deleting the existing database
• LINQ
◦ How do you work with the data in the application?
◦ Without using SQL
29
Specifying constraints
• 2 methods
◦ Data annotations in model classes, e.g.
[Required]
public string Name { get; set; }
◦ Fluent API
• Personal preference
◦ Fluent API
◦ Keeps class definitions clean and readable
◦ More comprehensive than data annotations
◦ Allows complex relationships between classes
30
Organizing Fluent
configurations
• Convenient to organize fluent configurations for each class in a separate configuration
class
◦ EntityTypeConfiguration
◦ But, not yet supported in EntityFrameworkCore (Jan 2018)
◦ [Link]
• Add file [Link] in DataAccess project
◦ Adapt code in listing 2-11
◦ Use Ctrl+. To fix compile errors
public class AnimalTypeConfiguration : EntityTypeConfiguration<AnimalType>
{
public AnimalTypeConfiguration()
{
ToTable("Species");
Property(p => [Link]).IsRequired();
}
}
31
Organizing Fluent – contd.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
[Link](new AnimalTypeConfiguration());
}
• In [Link], add the OnModelCreating() method
◦ Invoked when the database is created
◦ Invoke the fluent configuration
◦ adapted from JL listing 1-6
• Test newly added Fluent configuration
◦ Delete database
◦ Run application
◦ Check the database for changes
32
Fluent configuration
observations
• Model classes have no reference to the constraints
◦ Look as clean as before
◦ Data Annotations can clutter up the class definitions
◦ And mix database constraints into POCO classes
• All database constraints are now defined in a separate file
◦ [Link]
◦ In the project with the DbContext definitions
◦ This project has 2 files
◦ Database context definition
◦ Database model constraint definitions
33
Some fluent methods
• HasKey(t => [Link]);
◦ Specifies that Identifier column is the primary key
• HasKey(w => new { [Link], [Link] });
◦ Specifies that Provider and ProviderUserId are the composite key
• HasMany(p => [Link]).WithRequired(v => [Link]);
◦ One to many relationship
◦ Note: cannot be done in our example since patientId is not a class
◦ See JL Example 4-6 and Fig 4-2
• Property(p => [Link]).IsRequired().HasColumnName("StartDate");
◦ Specifies database column
34
Developer convenience
feature - Initialization
• During development, it is convenient for code first to modify database
schema, instead of deleting the database
static void Main(string[] args)
{
[Link](
new
[Link]<VetContext>());
// OR
//[Link](
// new [Link]<VetContext>());
…;
}
35
Code first recommendations
• Fluent API over data annotations
◦ Data annotations are convenient
◦ But Fluent is more comprehensive
◦ Also much cleaner to read
◦ Subjective opinion
• Implement model classes and entity configuration as a separate
solution
◦ Class library
◦ Build target
◦ Reuse across solutions
36
Database location and
authentication
• We have connected to the default local SQL Server database
◦ How do you connect to a specified database on a specific server
◦ How do you provide authentication information?
• Try connecting to SQL Server on your VM
37
Connection strings
• The connection parameters to the database are specified in the
application as the connection string
◦ Database location (IP address)
◦ Database instance
◦ Username, password
• Specified in [Link]
38
Connection string – contd.
"Data": {
"IEXTrading": {
"ConnectionString":
"Server=(localdb)\\MSSQLLocalDB;Database=IEXTrading;Trusted_Connection=True;
MultipleActiveResultSets=true"
}
}
• In [Link]:
[Link]<ApplicationDbContext>(options =>
[Link](Configuration["Data:IEXTrading:Connec
tionString"]));
39
Migrations
• Local database
◦ You can delete and create database at will
• Deployment servers
◦ Permissions are limited after initial database creation
◦ How do you
◦ add a column
◦ delete column
◦ change column type etc?
• Migrations (Any alternatives?)
◦ Note: As EF and .NET evolve, confirm migrations compatibility between
application framework and EF version used
◦ [Link]
40
Migrations – contd.
• Migrations references
◦ [Link]
enabling-migrations-in-a-real-project/
◦ [Link]
migrations-for-multiple-contexts-to-separate-databases
• Links refer to older version of Entity Framework
◦ But describe concepts nicely
◦ Verified Jan 2018
• Important ([Link]
◦ Using a corporate shared drive may prevent proper execution of EF install
scripts
◦ At USF, saving on U: breaks migration commands, even though regular EF functionality is fine
41
Migrations – contd.
• Two scenarios
◦ Setup database from scratch using migrations
◦ Migrations creates the tables
◦ Use SQL etc. to populate tables
◦ We are following this scenario
◦ Setup migrations with existing database
◦ Migrations modifies database from existing schema
◦ No data loss acceptable
◦ Julia Lerman’s blog post (verified Jan 2018):
◦ [Link]
migrations-with-an-existing-database
42
Migrating from scratch
• 2 steps
◦ Enable migrations
◦ Done one-time at the start of the project
◦ PM> Enable-Migrations
◦ Creates baseline model from existing database structure
◦ Add migration
◦ Done each time a model change is to be applied to the database
◦ PM> Add-Migration <Migration name>
◦ Detects the difference between current code-first model and all prior migrations
◦ Adds needed operations to pending migrations
◦ PM> Update-Database –verbose
◦ Applies these updates to the database
43
Enabling Migrations
• EF 6 known to be compatible with .NET framework
◦ But not with .NET Standard
• Tools → NuGet Package Manager → Package Manager Console → Select
Default Project: DataAccess
PM> Enable-Migrations
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded
migration '201801290114150_InitialCreate' corresponding to existing
database …
Code First Migrations enabled for project DataAccess.
44
Effects of enabling Migrations
• Migrations folder
added to the project
with the DbContext
◦ Check out the
contents of the Up()
method
◦ These statements are applied
to the database
45
Changing model
• To change model with migrations
◦ E.g.
◦ Add LastName property to Patient class
PM> add-migration 20180129LastName
◦ Check up() method in new migration
PM> update-database –verbose
◦ Verify database update
46
Naming migrations
• Personal experience
◦ Migrations accumulate
◦ Sorted by name
◦ But useful to have them sorted in creation order
• Useful naming convention
◦ yyyymmdd<MigrationImpact>
◦ E.g. 20180129lastName
◦ Ensures sort by date
◦ Across years, months and days
• More details
◦ Check out first blog link in migrations references (slide) for examples
◦ Also MSDN documentation etc.
47
Exercise
• Update the VetOffice object model by adding 2 relevant and related
classes
• Use migrations to update the database with the updated object model
• Use the new classes in queries
48
Migrations – with existing
databases
• [Link]
migration-for-an-existing-database-in-entityframework-4-3
• [Link]
3-code-first-migrations-with-an-existing-database
• [Link]
first-with_26.html
49
LINQ
• Querying entities typically done using Linq
◦ Language integrated Query
◦ Filter items in database using SQL-like syntax
◦ But strongly typed, e.g.
// [Link]
int checkYear = [Link](-2).Year;
Visit RecentJohnFirstVisit = testContext
.Patients
.Include(p => [Link])
.Where(p => [Link] >= checkYear)
.Where(p => [Link] == "John")
.FirstOrDefault()
.Visits
.FirstOrDefault();
50
LINQ usage - where
• Common constructs used in Linq queries
• Where
◦ Apply constraints
◦ E.g.
Visit RecentJohnFirstVisit = testContext
.Patients
.Include(p => [Link])
.Where(p => [Link] >= checkYear)
51
LINQ usage - select
• Select
◦ Retrieve collections
◦ E.g. add a list of comments to each visit
public class Visit
{
public …
public List<VisitComment> Comments { get; set; }
}
public class VisitComment
{
public int Id { get; set; }
public int VisitId { get; set; }
public string Comment { get; set; }
}
52
LINQ usage - select
• Select
◦ Retrieve collections
◦ How to retrieve all the comments for the visits by a patient?
Visit RecentJohnFirstVisit = testContext
.Patients
.Include(p => [Link](vi => [Link]))
.Where(p => [Link] >= checkYear)
.Where(p => [Link] == "John")
.OrderByDescending(p => [Link])
.FirstOrDefault()
.Visits
.FirstOrDefault();
53
LINQ usage - Include
• Entity framework tries to optimize queries
◦ Related objects are not loaded unless specifically asked for
• Include asks for related entities to also be retrieved from the database
• Consider 2 queries
◦ What is the difference in outputs?
◦ Why?
Visit RecentJohnFirstVisit1 = testContext Visit RecentJohnFirstVisit2 = testContext
.Patients .Patients
.Where(p => [Link] >= checkYear) .Include(p => [Link])
.Where(p => [Link] == "John") .Where(p => [Link] >= checkYear)
.OrderByDescending(p => [Link]) .Where(p => [Link] == "John")
.FirstOrDefault() .OrderByDescending(p => [Link])
.Visits .FirstOrDefault()
.FirstOrDefault(); .Visits
.FirstOrDefault();
54
Next steps
• Some concepts I’ve encountered in the past
◦ May be useful
◦ May be obsolete as EF evolves
55
Relationship fix-up
• Queries typically allow selection at top level
◦ Select Patients meeting certain criteria
◦ E.g. Patients over age 50
• What if
◦ you also wanted to filter visits by certain criteria?
◦ E.g. Visits by these patients this year
• Relationship fix-up is useful
◦ Select patients and visits separately
◦ EF will link all visits with their related patients
• [Link]
[Link]
56
Modeling inheritance
• How do you model inheritance in general?
◦ Table per hierarchy
◦ 1 common table for all classes in the hierarchy
◦ Common columns for base class fields
◦ Discriminator column
◦ Value in row == <class name>
◦ Plus, columns for inherited classes
◦ Table per type
◦ 1 table for base class
◦ Separate tables for specialized classes
◦ With foreign key to base class
57
Modeling inheritance – contd.
• Table per concrete type
◦ One table per class
◦ Includes all fields from all inherited classes
• Personal preference
◦ Fewer joins
◦ Easier to understand
◦ But more redundancy
◦ Change in base class requires change in all concrete classes
58
Modeling inheritance – contd.
• [Link]
mapping-strategies-with-entity-framework-code-first-ctp5-part-1-
[Link]
◦ Inheritance with EF Code First: Part 1 – Table per Hierarchy (TPH)
59
Domain models
• Layered architectures are common in modern applications
• In model-driven design, the domain layer represents the model of the
business
◦ Rest of the architecture (services etc) solve complex technical problems
User interface layer
Application layer
Domain layer (e.g.
code-first models)
Infrastructure layer
(e.g. EF dbContext)
60
Entity vs Value objects
• Source: Eric Evans, Domain-driven design
• Consider
◦ Object: User, customer
◦ Object: State, Country etc
• User is an example of an entity
◦ Defined by a thread of continuity through a life-cycle, an identity, not just a set of attributes
◦ Need to be matched with other objects even if attributes differ (e.g. during integration)
◦ We care about who or which they are
◦ Two people with the same name may or may not be the same person
• State is an example of a value object in most business applications
◦ Have no conceptual identity for the application
◦ Represents a descriptive aspect of the domain
◦ We only care for what they are
61
Modeling entities and value objects
• Entities
◦ Keep class definition simple
◦ Find ways of distinguishing objects
◦ Define what it means to be the same thing
• Value objects
◦ Focus on expressing the meanings of its attributes
◦ Generally, treat value objects as immutable
◦ i.e. cannot be changed by the application
◦ Whole value pattern
◦ Gather all relevant attributes into the value object, and make the value object a property of an entity
◦ E.g. put street, city, postal code etc in an address object and make the address object a property of
the customer entity
◦ Simplifies entities
62
Services
• Models are classes
◦ But many concepts in a domain are not things
◦ They are activities (verbs, not nouns)
◦ And are not a natural responsibility for an entity or value object in the
model
◦ E.g. SendEmailService, TransferFundsService
• Services are operations performed for clients (typically entities)
◦ Defined in terms of what they can do for a client
◦ Have no state (any client can use any instance of the service at any time)
63
Other important model concepts
• Explicit constraints
◦ Require data that is not a part of the object’s definition
◦ Consolidates rules into one object
◦ Simplifies focus on constraints by isolating them into constraint objects
• Specifications
◦ Value objects that test whether an object satisfies some criteria
◦ E.g. IsDelinquent()
◦ Useful for validation, selection and building to order
• Processes
◦ Can be modeled as services
◦ Make important algorithms into objects
64
Summary
• Background
• Code first components
• Entity framework example
• Loose ends
◦ Constraints - Fluent API and Data Annotations
◦ Connection strings - Database selection
◦ Migrations
◦ LINQ
• Entity Framework in MVC
65