Entity Framework additional notes: part 2

advertisement
.NET Database Technologies:
Entity Framework
additional notes – part 2
EF1 => EF4
• “The 1.0 release of the Entity Framework was not a
resounding success – developers found themselves
fighting the framework”
• EF4 gives you the choice of how to work
• Database-first, model-first, code-first
• Supports POCO entities for Persistence Ignorance
POCO support
• EF1 entity classes inherit from EntityObject
• Difficult to separate concerns in application

Classes are difficult to unit test

For unit testing, want to “fake” persistent storage
• Difficult to switch DAL technology

Can’t take existing classes and use EF1

Need to redesign classes significantly to bind them to EF
• EF4 allows you to use POCOs
• Model classes can be completely ignorant of persistence
mechanism
POCO classes
• POCO classes must work in conjunction with EDM
• Must mirror entities defines in EDM
• However, EDM does not generate the classes

Set Code Generation Strategy to none in designer properties
• Two ways to create classes

Write POCO code by hand

Use a T4 Template
•
Microsoft ADO.NET C# POCO Entity Generator
•
Download from www.visualstudiogallery.com
•
Right-click EDM designer surface and select Add Code
Generation Item
•
Creates template for generating POCOs to match EDM
T4
• Text Template Transformation Toolkit
• Code generation tool built into Visual Studio
• Can be used in many different code generation scenarios
• Template file has .tt extension
• When a project has a .tt file, the template is processed at
build time
• Generated code file(s) associated with template in Solution
Explorer, but can be moved elsewhere if required
Managing POCOs
• Need to create a custom ObjectContext class
• Should have an ObjectSet for each entity type
• Needs to know name of EDMX file (passed in as a
constructor parameter) to allow it to access mapping and
storage information
Issues with POCOs – change tracking
• Change tracking
• Classes derived from EntityObject constantly communicate
with ObjectContext
• POCOs can’t do this
• ObjectContext has to track changes to POCOs:

DetectChanges method

SaveOptions -> DetectAllChanges forces call to DetectChanges
before saving

Default behaviour
Issues with POCOs – loading related data
• EntityObject can load related data with Load method

e.g. employee.AddressesReference.Load()

Navigation property also has an EntityReference property
• POCO does not have EntityReference properties

Need to load related data from context

e.g. context.LoadProperty<Employee>(
employee, e => e.Addresses)
• Can also support lazy loading with POCOs through
dynamic proxies (see later)
Issues with POCOs – two-way relationships
• Context forces EntityObject classes to be aware of two-
way relationships and keeps relationships in sync
• Options for doing this with POCOs:

Call DetectChanges method of context

Write code in POCO classes so that they manage their own
relationships

Use dynamic proxies
Dynamic proxies
• POCO classes can be wrapped by proxy classes which are
created dynamically at runtime
• Proxy class is derived from POCO class
• POCO properties must be marked as virtual
• Adds EF-specific behaviour which allows management of
change tracking, lazy-loading and relationships in the
same way as EntityObject classes
• Client code works with POCO classes, but actual objects
instantiated are proxies
• EF uses reflection to find out about properties of POCOs
and Reflection.Emit to dynamically generate IL code for
proxy classes
POCOs and PI
• POCOs do not need to derive from any persistence specific
class
• Do not use persistence specific collection types

Should use ICollection as collection property type
• Requirement for properties to be virtual to support some
capabilities through proxies

This does not violate PI – classes don’t need to know about
what the derived classes will do
• EF4 POCO support allows PI domain classes to be used
Using a repository
• Rather than having client code query context directly it is
common to use a repository
• A repository “Mediates between the domain and data
mapping layers using a collection-like interface for
accessing domain objects” (Fowler)
• Promotes testability

Can swap in fake context with affecting client/test code
• Can program client to an interface for repository and
define actual repository type through dependency injection

Allows DAL to be swapped easily
• Context implements Unit of Work pattern, but often wrap
this in UoW class/interface to allow further isolation of
dependencies
IoC and Dependency Injection
• Inversion of Control (IoC)

Objects do not create other objects on which they rely to do
their work

Instead, they get the objects that they need from an outside
source (for example, an xml configuration file)
• Dependency Injection (DI)

This is done without the object intervention, usually by a
container that passes constructor parameters and set
properties
• Castle Windsor is an example of a .NET DI container
• Can manage dependencies for all kinds of service, not just
persistence
• http://msdn.microsoft.com/en-us/library/aa973811.aspx
Creating a repository
• Pattern describes solution to problem, but does not strictly
define how to write the code
• Many variations on the Repository pattern are possible
• You can design your own – there are plenty of articles and
blog posts with examples to base it on
• You can use a template to generate your basic
implementation from an EDM

ADO.NET Unit Testable Repository Generator
•

Download from www.visualstudiogallery.com
EFRepository
•
Download from efrepository.codeplex.com
Model-First
• All examples so far have been re-engineered from the
database
• Changes to the conceptual model were mapped to the
original database
• EF4 allows you to start by designing the conceptual model
and then use that model to define the database
• Model-First
Creating the conceptual model
• Add new ADO.NET Entity Data Model item to project and
select Empty Data Model in wizard
• Add new Entities to model using Toolbox or right-click on
designer surface
• Add properties (scalar or complex) to each entity by right-
clicking on entity

Set type of property in Properties window

Give each entity a key property
• Add associations by right-clicking on surface or entities

Adding association creates navigation properties
• Create inheritance hierarchy by specifying base class for
new entities
Generate database
• Right-click on designer surface and select Generate
Database from the Model
• Slightly misleading name

Database must exist – designer will generate DDL to add to
database

Designer does not execute the DDL script it creates – have to
do that separately
• DDL Generation wizard allows you to specify the database,
and creates connection string in app.config
• Wizard adds SSDL and MSL portions to EDMX file and
creates SQL script in project folder
DDL generation
• Based on a T4 template
• Table names come from EntitySet names
• Property and association attributes set in designer will be
reflected in column attributes, e.g. data types, cascade
delete
• Inheritance will be implemented with a TPT strategy
• Many-to-many relationship implemented with a join table
Customising DDL generation
• Possible to modify T4 template
• Only template installed in VS2010 is SSDL to SQL 10.tt
• Or use Entity Designer Database Generation Power Pack

Download from www.visualstudiogallery.com

Contains additional templates

Can force TPH strategy for inheritance

Provides capability to migrate existing database after making
changes to model
Model-First and POCOs
• Model-First approach is compatible with POCOs
• Once EDMX has been created, you can create POCOs to
mirror entities and ObjectContext class to manage them
• Alternatively, the entities you create in the designer can
be based on knowledge of existing POCO classes
Code-First
• Avoid altogether working with visual model
• Build your model with POCO classes
• Moving towards true Domain Driven Design
• Microsoft consulted with a Data Programmability Advisory
Council which included Fowler, Evans and Nilsson
• Currently this feature is a CTP, not included in the release
of VS2010

Need to download and install

Add reference to Microsoft.Data.Entity.Ctp.dll which is installed
in Program Files\Microsoft ADO.NET Entity Framework Feature
CTP5\Binaries

Add using System.Data.Entity where required
What does Code-First do?
• You need to create POCOs and a context class which
inherits from DbContext
• Defines DbSet property to store a set of each entity class
• At runtime it reads your class definitions and creates in-
memory representation of CSDL, MSL and SSDL
• Looks for connection string that has the same name as the
context class
• Uses convention-based persistence mapping
• Convention over configuration
• Creates database if it doesn’t already exist (SQL CE and
SQL Express)
Customising mapping
• Override OnModelCreating event of DbContext and use
ModelBuilder class to customise mapping

Change table names

Customise column/property mapping

Split a table across multiple types

http://weblogs.asp.net/scottgu/archive/2010/07/23/entityframework-4-code-first-custom-database-schemamapping.aspx
• Data annotation attributes

Specify keys, string lengths, etc

http://blogs.msdn.com/b/efdesign/archive/2010/03/30/dataannotations-in-the-entity-framework-and-code-first.aspx
EF4 options - summary
• Database-First

Define model and mappings in EDMX

Entities are EntityObjects or POCOs
• Model-First

Define model in EDMX

Entities are EntityObjects or POCOs
• Code-First

Define model with POCOs

Mappings defined by convention or ModelBuilder/annotations

Entities are POCOs
Profiling EF
• Profile at server

SQL Server Profiler
• Profile at client

EF Profiler

http://efprof.com/

Not free!
Download