Models and patterns
Download
Report
Transcript Models and patterns
.NET Database
Technologies:
Data Models and
Patterns
Evolution of Data Models
Hierarchical Databases
• Data organised in a tree
a parent can have many children
a child can have only one parent
• Records described by entity types
• 1:N (one-to-many) relationships
• Query by path navigation
• Examples
File system
LDAP
Windows Registry and Active Directory
XML documents and XQuery
Network Databases
• Data organised in graph (lattice)
a parent can have many children
a child can have many parents
• Query by graph navigation
• Examples
CODASYL
Relational Databases
• Data organised as tuples in relations
• Link between data tuples
primary and foreign keys
• Relational algebra
project, select, join
• Relational normal forms
• Declarative language
data definition, consistency, manipulation and querying
• Examples
Microsoft SQL Server, Oracle, MySQL...
Relational Databases
• Relational model is very simple
only basic concepts → references need to be simulated
restricted type system → no user-defined types
• Lack of semantic modelling
complex data, versioning, roles
• Little support for data and schema evolution
• Object-relational impedance mismatch
Object-Relational Impedance Mismatch
• A set of conceptual and technical difficulties that are often
encountered when a relational database management
system is being used by a program written in an objectoriented programming language
• Object-oriented application development and relational
data management results in clash of two incompatible
models
• Code to map between models represents considerable
overhead, costly and hard to maintain
Solutions to the Impedance Mismatch
• Object-Oriented Databases
data represented as objects
object identity, references, relationships, associations
user-defined types, abstract data types, inheritance
• Object-Relational Databases
relational model extended with nested relations, references,
sets, row types, abstract types, functions
commingling of models
• Object-Relational Mapping
most widely-adopted solution due to dominance of relational
databases
overhead can be mitigated by use of frameworks such as
Entity Framework, NHibernate
Characteristics of Relational Model
• Philosophy
Efficiency, data integrity, mathematical basis (relational
algebra/calculus)
• Identity
Primary key column(s)
• Associations
Foreign Keys - enforce referential integrity
One-to-many or one-to-one
Many-to-many associations require association table
• Navigation
Associations are not directional
find related entities by JOIN expression in query
Relational Model Example
Characteristics of Object Model
• Philosophy
Rich domain model
• Identity
Each object has unique identifier
Not a property of the object
• Associations
Single object or object set references
Can model many-to-many with object set references in both
classes
• Navigation
Associations can be navigated in one or both directions
depending on references
Navigate through object graph by following references
Object Model Example
Customer
Order
-dateReceived : Date
-ordNumber
-CalcDiscPrice()
+CalcPrice()
*
1
-lastName : string
-firstName : string
-discount : float
+GetDiscount()
1
*
-orderLines
Product
-product
OrderLine
-quantity : int
+GetLinePrice()
1
1
-name : string
-productID : string
-price : decimal
+GetPrice()
Characteristics of Object Model
• Behaviour
Methods can implement business logic in object, e.g.
Validation
• Integrity and consistency
Integrity not enforced but supported by use of references
Many need to write code to maintain consistent associations
Particularly true when association is bi-directional
• Inheritance
• Interfaces
• Composition/aggregation of objects
Options for Dealing with the Mismatch
• Work in your application with objects which closely mimic
the structure of your database
ADO.NET Datasets, DataTables, etc
• Work in your application with objects and map their
properties and associations to database table columns
Object-Relational Mapping (ORM)
Can use rich domain model
Store mapped properties in database for persistence
Reconstruct domain objects from data in database
Depending on complexity of model, may need to deal with a
range of issues which arise from the mismatch
Patterns Relating to ORM
• A design pattern is a general reusable solution to a
commonly occurring problem in software design
• Gang of Four (GoF) patterns are the most famous and can
be applied in many situations
• Fowler’s Patterns of Enterprise Application Architecture
(PoEAA) includes patterns which are useful in ORM
• Patterns are not specific code solutions
General approaches to solving problems
Establish a vocabulary for describing solutions
Many variations and specific implementations may
be found for a given pattern
Fowlers illustrative examples are largely in Java but
examples in C# can be found
Patterns Relating to ORM
• The following descriptions are mainly taken from PoEAA
Brief summaries are at: http://martinfowler.com/eaaCatalog/
Full descriptions and illustrative code can be found in book
• They provide a useful summary of issues which must be
considered in implementing ORM
• Some are implemented by frameworks such as NHibernate
• Some are applicable in code which makes use of
frameworks
Domain Model
• An object model of the domain that incorporates both
behaviour and data
• At its worst business logic can be very complex
• Rules and logic describe many different cases and slants of
behaviour, and it's this complexity that objects were
designed to work with
• A Domain Model creates a web of interconnected objects,
where each object represents some meaningful individual,
whether as large as a corporation or as small as a single
line on an order form
Active Record
• An object that wraps a row in a database table or view,
encapsulates the database access, and adds domain logic
on that data
• Active Record uses the most obvious approach, putting
data access logic in the domain object
• This way all people know how to read and write their data
to and from the database
• Castle ActiveRecord and Ruby on Rails are well-known
implementations of this pattern
Data Mapper
• When you build an object model with a lot of business
logic the object schema and the relational schema often
don't match up.
• The Data Mapper is a layer of software that separates the
in-memory objects from the database.
• The in-memory objects needn't know even that there's a
database present; they need no SQL interface code, and
certainly no knowledge of the database schema
• Objects may be POCOs or may have to inherit from a
persistence base class
• NHibernate, LINQ to SQL, etc
What are POCOs?
• Plain Old CLR Objects
• POCOs are objects unencumbered with inheritance or
attributes needed for specific frameworks
• Sometimes called PONOs (Plain Old .NET Objects)
• Term derived from POJO, a term commonly used in the
Java world
Metadata Mapping
• Much of the code that deals with object-relational mapping
describes how fields in the database correspond to fields in
in-memory objects
• The resulting code tends to be tedious and repetitive to
write
• A Metadata Mapping allows developers to define the
mappings in a simple tabular form, which can then be
processed by generic code to carry out the details of
reading, inserting, and updating the data
• Metadata can be in classes, XML files, attributes or simply
naming conventions
Identity Field
• Relational databases tell one row from another by using
the primary key.
• Objects don't need such a key, as the object system
ensures the correct identity
• Reading data from a database is all very well, but in order
to write data back you need to tie the database to the inmemory object system
• Identity Field is simple - all you do is store the primary
key of the relational database table in the object's fields
Foreign Key Mapping
• Objects can refer to each other directly by object
references
• Even the simplest object-oriented system will contain a
objects connected to each other in all sorts of interesting
ways
• To save these objects to a database, it's vital to save
these references.
• Map an association between objects to a foreign key
reference between tables
Association Table Mapping
• Saves an association as a table with foreign keys to the
tables that are linked by the association
• Maps a many-to-many association in the object model to
two one-to-many associations in the database
Single-Table Inheritance
• Relational databases don't support inheritance, so when
mapping from objects to databases we have to consider
how to represent inheritance structures in relational tables
• When mapping to a relational database, we try to
minimize the joins that can quickly mount up when
processing an inheritance structure in multiple tables
• Single Table Inheritance maps all fields of all classes of an
inheritance structure into a single table
discriminator field
Class Table Inheritance
• You want database structures that map clearly to the
objects and allow links anywhere in the inheritance
structure
• Class Table Inheritance supports this by using one
database table per class in the inheritance structure
• Need to join tables to construct a single instance in
memory
Concrete Table Inheritance
• Thinking of tables from an object instance point of view, a
sensible route is to take each object in memory and map it
to a single database row
• This implies Concrete Table Inheritance, where there's a
table for each concrete class in the inheritance hierarchy
• Changes in schema may need to be replicated across
several tables
• NHibernate supports these inheritance mapping options
Repository
• A system with a complex domain model often benefits
from a layer, such as the one provided by Data Mapper
that isolates domain objects from details of the database
access code
• In such systems it can be worthwhile to build another
layer of abstraction over the mapping layer
• A Repository mediates between the domain and data
mapping layers, acting like an in-memory domain object
collection
• Objects can be added to and removed from the
Repository, as they can from a simple collection of objects,
and the mapping code encapsulated by the Repository will
carry out the appropriate operations behind the scenes
• Can write a Repository which uses, e.g., NHibernate for
mapping
Unit of Work
• When you're pulling data in and out of a database, it's
important to keep track of what you've changed;
otherwise, that data won't be written back into the
database
• Similarly you have to insert new objects you create and
remove any objects you delete.
• You can change the database with each change to your
object model, but this can lead to lots of very small
database calls, which ends up being very slow.
• Furthermore it requires you to have a transaction open for
the whole interaction, which is impractical if you have a
business transaction that spans multiple requests
Unit of Work
• A Unit of Work keeps track of everything you do during a
business transaction that can affect the database
• When you're done, it figures out everything that needs to
be done to alter the database as a result of your work
• Examples of “ready-made” UoW:
ITransaction in Nhibernate
DataContext in LINQ to SQL
ObjectContext in EF
DataSet(!)
Identity Map
• If you aren't careful you can load the data from the same
database record into two different objects
• Can cause problems writing updates back to database
• If you load the same data more than once you're incurring
an expensive cost in remote calls
• An Identity Map keeps a record of all objects that have
been read from the database in a single transaction
• Whenever you want an object, you check the Identity Map
first to see if you already have it
• e.g. LINQ to SQL
DataContext maintains an
“identity cache”
Lazy Load
• For loading data from a database into memory it's handy
to design things so that as you load an object of interest
you also load the objects that are related to it
• No need to load all the objects he needs explicitly
• However, if you take this to its logical conclusion, you
reach the point where loading one object can have the
effect of loading a huge object graph
• A Lazy Load leaves a marker in the object structure so
that if data is needed it can be loaded only when it is used
• Can configure lazy/eager loading
in NHibernate
Lab – O/R Mapping Scenario
• Task 1. Map a given object model to a database schema
• Task 2. Implement the database and a Data Mapper class