/
Object-Relational Mapping in the Microsoft World Object-Relational Mapping in the Microsoft World

Object-Relational Mapping in the Microsoft World - PowerPoint Presentation

conchita-marotz
conchita-marotz . @conchita-marotz
Follow
436 views
Uploaded On 2016-08-03

Object-Relational Mapping in the Microsoft World - PPT Presentation

by Benjamin Day Benjamin Day Consulting Inc About the speaker Owner Benjamin Day Consulting Inc Email bendaybendaycom Web httpwwwbendaycom Blog httpblogbendaycom Trainer ID: 430836

class property object business property class business object nhibernate database true column sql null mapping objects nhibernateresearch key linq

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "Object-Relational Mapping in the Microso..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

Object-Relational Mapping in the Microsoft World

by Benjamin DayBenjamin Day Consulting, Inc.Slide2

About the speaker

Owner, Benjamin Day Consulting, Inc.Email:

benday@benday.com

Web:

http://www.benday.comBlog: http://blog.benday.comTrainerVisual Studio Team System, Team Foundation ServerMicrosoft MVP for C#Microsoft VSTS/TFS Customer Advisory CouncilLeader of Beantown.NET INETA User GroupSlide3

Agenda

Overview of “the problem”Brief discussion of the optionsLINQ to SQLNHibernateEntity FrameworkSlide4

The PROBLEMSlide5

The Problem

Mismatch between objects and relational databasesObjects = inheritance, polymorphism, compositionDatabase = rows of data with relationships to other rows of dataSlide6

One Table Per Class

The class looks like the tableGreat candidate for a typed datasetSimple

Works nicely with DataAdapter because of RowStateSlide7

Limitations of Typed Dataset Route

Tight coupling with the databaseInheritance is difficultHow do you validate data?Null, data type, and length check validation is handled

Serious validation lives outside of the dataset

 not very object-oriented

The ‘object’ route is better for validationValidation goes in the “set” propertySlide8

Object - DataRow Hybrid

Every object wraps a typed DataRowProperties control access to columns on the DataRow Facilitates more complex validationDataRow becomes a data transfer objectStill works nicely for System.Data integrationSlide9

Primitive Obsession

Validation in the get / set properties is ok but is phone number validation really the responsibility of the Person class? James Shore’s “Primitive Obsession”Too many plain scalar valuesPhone number isn’t really just a string

http://www.jamesshore.com/Blog/Slide10

Coarse-Grained vs. Fine-Grained Object Model

Fine-grained = More object-orientedData and properties are split into actual responsibilities

coarse-grained

fine-grainedSlide11

But how do you save it?

Four classes go to one table?Five instances go to one table?Slide12

Inheritance, Collections, and Relationships

Employee is a PersonEmployee has UnderlingsEmployee has a SupervisorSlide13

Limitations of Object - DataRow Hybrid

Inheritance  >1 DataRow at onceOne for base class, one for descendent

Which instance of DataSet is the object using?

Complicates saves

Client has to worry about the internal state of the objectHow to save parent-child relationships? Employee has FK to a Supervisor  Supervisor needs to be saved firstObjects have ability to modify internal state of other objects wrapping the same DataSet  bugs & encapsulationNumber of records in the DataSet tends to grow rather than shrink

How to clear out old, unused records in the DataSet? How do you know when they’re old? Slide14

Object-Only Model

No more DataRowsClasses are member variables, methods and propertiesClean “Domain Model” patternBusiness tier worries about itselfDecoupled from the databaseStraightforward inheritance, polymorphismSlide15

Complications in the Object-Only Model

Data access (“Mapper”) tier has to “adapt” data and structures from the database into populated business objects and vice versaHow to manage IsDirty for INSERT vs UPDATE? Adding IsDirty logic to domain objects is a violation of the “separation of concerns”

Concurrency management?

Transaction management?Slide16

Do you really want to solve these problems?

Problems are solvableEverybody writes their own solutionPersistence is a distraction from solving The Real Business ProblemSlide17

Available OptionsSlide18

Options

LINQ to SQLEntity FrameworkNHibernateWilson OR Mapper

LLBLGen

And more…Slide19

LINQ to SQL

Available in Visual Studio 2008“Better typed dataset”Slide20

LINQ to SQL: Pros / Cons

ProsYou don’t have to write data access codeGood for Rapid Application Prototyping

Integrated into Visual Studio

Designer support

Will generate the database schema for youConsSQL Server onlyLimited inheritance modeling (Table Per Hierarchy only)Closely tied to the databaseUnusual way of handling stored procedures

Generates codeSlide21

Entity Framework

Microsoft’s first, real ORM solution(well…I guess this depends on who you talk to)In betaRumored to be released with Visual Studio 2008 sp1Slide22

Entity Framework: Pros / Cons

Pros

Full-featured

Not open source

Integrated into Visual StudioDesigner support (eventually)Support for non-SQL Server databases (eventually)Supports LINQSupport Table-per-TypeCons

Still in beta

Not open source

Version 1Slide23

NHibernate

Full-featured ORM solutionOpen sourceBased on Java’s Hibernate frameworkUses XML to map tables/columns to objects/propertiesSlide24

NHibernate: Pros / Cons

ProsRich selection of mappings

Inheritance

modelling

Polymorphic queriesEstablished solution with lots of current usersSupport for multiple database vendorsOpen sourceFreeConsOpen sourceFree

Not from Microsoft

3

rd

party library

Limited to zero GUI support

Currently doesn’t support LINQ

…but does have HQLSlide25

LINQ to SQLSlide26

Using the LINQ to SQL O/R Designer

Define classesSet up inheritanceSlide27

LINQ to SQL vs. Typed DataSets

My $0.02 – LINQ to SQL is the new Typed DataSetSlide28

LINQ to SQL vs. LINQ to DataSets

DataSets in VS2008 are query-able with LINQDataTable’s object model has changed

DataTable

now extends from

TypeTableBase<T>TypedTableBase<T> extends DataTableBackwards compatibleNo special way to fill the DataSet/DataTable with LINQ to SQL

Still uses

DataAdapterSlide29

LINQ to SQL vs. Raw SQL Access

Hopefully you don’t do this…The data access strategy of masochists everywhereSlide30

LINQ to SQL vs. NHibernate

NHibernate is LINQ to SQL’s older, more successful cousin

5+ years in .NET & Java

Full-featured ORM framework

Maps tables/columns to classes/propertiesUses xml mapping files or attributesComprehensive inheritance modelingHas LINQ-like object query syntax HQL – Hibernate Query LanguageMulti-vendor database support

Oracle,

SQLServer

(2000 & 2005),

MySql

, Sybase, etc

Lets you focus on the business problem rather than persistenceSlide31

Using LINQ to SQL with Unit Tests

When testing database code, database must be in a known stateEasiest way:Wipe the database between testsDataContext.DeleteDatabase()DataContext.CreateDatabase()

Database schema always in sync with code

Harder way:

Unit test manages transactionRollback at end of unit testSlide32

LINQ to SQL in an n-tier Application

Common BaseClassHooking into save eventsAuto-updating: ModifiedDate, ModifiedByKeeping your code organized with the “Service Layer” patternSlide33

Common Business Base Class

Each business class should probably have similar fieldsIdModifiedDate, ModifiedByCreateDate, CreatedByBummer: LINQ to SQL isn’t great at this

(NHibernate does this effortlessly)

Mapped columns must be defined on the concreteSlide34

Code Demo

Introduce a common business base classSlide35

Code Demo

Implement the partials and auto-populate the base class propertiesSlide36

Auto-update base class propertiesfrom

DataContextGenerated DataContext & other objects are partial classesGenerated code gives you partial methods on DataContext for each object

InsertXxx(), UpdateXxx(), DeleteXxx()

Create your own partial class and create your own implementation of the method

Don’t forget to call ExecuteDynamicInsert(), ExecuteDynamicUpdate() or ExecuteDynamicDelete()Slide37

Other fun stuff with the partial methods

Your partial implementations wipe out the LINQ to SQL default implementation(Who cares? This is boring.)You could put your own implementation that uses stored procedures in your partials!Slide38

Service Layer Pattern

From “Patterns Of Enterprise Application Architecture”

by Martin Fowler, Randy Stafford, et al.

Chapter 9

“Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation.”

-Randy StaffordSlide39

Why Service Layer?

Formally defines supported business tier operations (aka methods)Methods provide ideal target for unit testingKeeps code organizedCode review: anything complex not in the service layer

 refactor

Keeps code out of the UI

Isolates the Domain Model (business) objectsMinimize usage of the Domain Model objects outside of the Business tierSlide40

Service Layer in LINQ?

CRUD operations for each business object Any specialized “get” operationsCentralized place for any custom from-where-select’sFactory methods

Create a

BusinessFacade

<T>Slide41

Entity FrameworkSlide42

Entity Framework Overview

Still in betaOfficial release with VS2008 sp1Trying to be more than just an ORM3 layers

Conceptual Model (classes)

Storage / Logical Model (table definitions)

Mapping layer Slide43

NHibernateSlide44

What NHibernate

isn’t“Hibernate” has nothing to do with Windows HibernateNot object serializationNot a code generatorSlide45

NHibernate To The Rescue

.NET port of the Java-based Hibernate Object-Relational FrameworkNHibernate 1.2 is (roughly) Hibernate

2.1 + some features of Hibernate 3.0

Hibernate's goal is to relieve the developer from 95 percent of common data persistence related programming tasks.”Facilitates saves and retrieves of objects“Hibernate provides transparent persistence, the only requirement for a persistent class is a no-argument constructor.”Keeps your objects cleanOpen-source, free software under LGPL

http://www.jboss.org/opensource/lgpl/faq

Ported by Tom Barrett, Mike

Doerfler

, Peter

Smulovics

, and Sergey

KoshcheyevSlide46

What is it?

Object Relational Mapping FrameworkXML-basedMapping files *.hbm.xml

Classes/Properties

Tables/Columns1+ mapping fileshibernate.cfg.xmlDatabase Dialect: SQL Server, Oracle, MySQL, etc.Which assemblies to manageWhich mapping files to useSlide47

What it will do for you.

Make your life easierSimplify your data accessAllow you to focus on your business tierSlide48

hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8" ?><hibernate-configuration xmlns="urn:nhibernate-configuration-2.0" >

<session-factory name="NHibernate.Test">

<!–- Writes all SQL to Console

--> <property name="show_sql">true</property> <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>

<!–- SQL SERVER

-->

<property name="connection.connection_string"

>Server=localhost\sql2005;initial catalog=bugs;User ID=sa;Password=sa_password;Min Pool

Size=2</property>

<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>

<property name="connection.driver_class“

>NHibernate.Driver.SqlClientDriver</property>

<!-- mapped assemblies -->

<mapping assembly="NHibernateResearch.Business" />

</session-factory>

</hibernate-configuration>Slide49

Mapping files (*.hbm.xml)

<?xml version="1.0" encoding="utf-8" ?><

hibernate-mapping

xmlns="urn:nhibernate-mapping-2.0">

<class name="NHibernateResearch.Business.Person, NHibernateResearch.Business"

table="Person"

>

<

id

name="PersonId" type="System.Int32" unsaved-value="0">

<generator class="native" />

</id>

<timestamp name="LastModified" />

<

property

name="FirstName" not-null="true"></property>

<property name="LastName" not-null="true"></property>

</class>

</hibernate-mapping>Slide50

<class>

Simplest mappingMaps a class to a database tableAttributes“name” = name of the persistent class

Fully qualified class name, assembly name (no “.dll”)

“table” = name of the table

Required element<id> = defines object identityCommon elements<timestamp>, <version> for optimistic concurrency<property> for mapping class properties to database columnsSlide51

<id>

<id name="PersonId" type="System.Int32" unsaved-value="0"> <generator class="native" />

</id>

Required element of <class> mapping

Used to establish object identity, database primary keyAttributes“name” – name of the property “column” – (optional) name of the table column

“type” – (optional) data type for the property

“unsaved-value” – used to determine INSERT vs. UPDATE

For “identity” columns, specify a <generator>

class=“native” uses int identity column (SQL Server) or sequence (Oracle)

class=“guid” generates guid keys

For non-”identity” columns use <composite-id>

This approach is strongly discouragedSlide52

<property>

<property name="LastName" not-null="true"></property>

<property name="

Html

"> <column name="HtmlContent" sql-type="text" not-null="true"></column></property>

Child element to <class>

Used to map a property to a database column

Attributes

“name” – name of the property

“column” – (optional) name of the database column

“not-null” – (optional) describes the nullability of the database column

defaults to nullable

“type” – (optional) datatype for the property

Optional <column> element describes information about the database column

“sql-type” attribute – override default column datatype

“length” attribute – override default column lengthSlide53

Mapping the Person class

<class

name="NHibernateResearch.Business.Person, NHibernateResearch.Business"

table="Person">

<id name="PersonId" type="System.Int32" unsaved-value="0"> <generator class="native" /> </id>

<property name="FirstName" not-null="true"></property>

<property name="LastName" not-null="true"></property>

<property name="Email" not-null="true"></property>

<property name="HomePhone" not-null="true"></property>

<property name="WorkPhone" not-null="true"></property>

</class>Slide54

The NHibernate Session

Main point of contactISession interfaceSessionFactory.OpenSession() Objects are associated the ISessionLazy loadingSave, delete, and retrieve operationsSlide55

Saving

SaveUpdate() Person person1 = new Person(); // create

person1.Name.FirstName = "firstname1";

// set properties

person1.Name.LastName = "lastname1";session.SaveOrUpdate(person1);session.Flush();session.Close();Slide56

Transactions

Call BeginTransaction() on the sessionpublic virtual void Save(object item)

{

ITransaction tx = null;

try { tx = m_session.BeginTransaction();

m_session.SaveOrUpdate(item);

tx.Commit();

}

catch (Exception ex)

{

if (tx != null) tx.Rollback();

throw ex;

}

}Slide57

Retrieving

Query / HQL syntaxHQL = Hibernate Query LanguageSQL-like queries against the object model Use for more complex queries (JOINs)Criteria syntaxBuild the query programmatically

NHibernate Allows Polymorphic QueryingSlide58

HQL Sample

Find Employees by Supervisor’s NameSlide59

HQL Sample

public IList FindSupervisorEmployees(

string firstName, string lastName)

{

string hqlQ

uery =

@"

from Person p

where p.Supervisor.FirstName = :firstName

and

p.Supervisor.LastName = :lastName";

IQuery query = Session.CreateQuery(

hqlQ

uery);

query.SetParameter("

firstName

",

firstName

);

query.SetParameter("

lastName

",

lastName

);

return query.List();

}Slide60

ICriteria: Load All By Type

Gets an IList of objects by type or interfacepublic IList GetList(

Type type

)

{ ICriteria criteria = m_session.CreateCriteria(type); return criteria.List();

}

Polymorphic queries

Piano : MusicalInstrument

Flute : MusicalInstrument

CreateCriteria(typeof(MusicalInstrument))

Returns mix of Piano and Flute objectsSlide61

ICriteria: Load By Property Value

Gets a list of objects by type where a property has a certain value

public

IList

Get(Type type, string propertyName, object propertyValue){

ICriteria criteria =

m_session.CreateCriteria(type);

crit

eria

.Add(Expression.Eq(propertyName, propertyValue));

IList list = crit

eria

.List();

return list;

}Slide62

Deleting

Session.Delete(object instance)Slide63

Making Person More Fine-grained

coarse-grained

fine-grained

fine-grainedSlide64

Mapping Fine-grained PersonSlide65

<component>

<component name="Name" class="NHibernateResearch.Business.Name, NHibernate

Research

.Business">

<property name="FirstName" not-null="true"></property> <property name="LastName" not-null="true"></property></component>Used to map columns in a table to properties on a different classObject does not have it’s own “identity”No primary key, no <id>

Only exists in relation to the containing class

Cannot save an instance of “Name” by itself to the databaseSlide66

Mapping Person Using <component>

<class name="NHibernateResearch

.Business.Person, NHibernateResearch.Business" table="Person">

<id name="PersonId" unsaved-value="0">

<generator class="native" /> </id> <component name="Name" class="NHibernateResearch.Business.Name, NHibernateResearch.Business"> <property name="FirstName" not-null="true"></property>

<property name="LastName" not-null="true"></property>

</component>

<component name="Email" class="NHibernateResearch.Business.Email, NHibernateResearch.Business">

<property name="Address" column="EmailAddress" not-null="true"></property>

</component>

<component name="WorkPhone" class="NHibernateResearch.Business.Phone, NHibernateResearch.Business">

<property name="Number" column="WorkPhone" not-null="true"></property>

</component>

<component name="HomePhone" class="NHibernateResearch.Business.Phone, NHibernateResearch.Business">

<property name="Number" column="HomePhone" not-null="true"></property>

</component>

</class>Slide67

Concurrency Columns

Child elements of <class>Must be declared immediately after the <id><timestamp> – uses date/time data to manage concurrency<version> – uses a numeric version idSlide68

Mapping Inheritance

Employee is a PersonSlide69

<joined-subclass>

<class name="NHibernateResearch.Business.Person, NHibernateResearch.Business" table="Person"> <id name="PersonId" unsaved-value="0">

<generator class="native" />

</id>

... <joined-subclass name="NHibernateResearch.Business.Employee, NHibernateResearch.Business" table="Employee"> <key column="EmployeeId"/>

<property name="Title" not-null="true" />

<many-to-one name="Supervisor" column="SupervisorId" not-null="false" cascade="save-update"></many-to-one>

<bag name="Underlings" lazy="true" inverse="true" cascade="save-update">

<key column="SupervisorId"></key>

<one-to-many

class="NHibernateResearch.Business.Employee, NHibernateResearch.Business"

></one-to-many>

</bag>

</joined-subclass>

</class>

Subclass gets its own table for its properties/columns

<joined-subclass> element goes inside of the superclass’ <class> or <joined-subclass> element

<key> element defines the name of the column to use to join from the superclass’ <id> (Person.PersonId

 Employee.EmployeeId)Slide70

Mapping Associations & Collections

Supervisor is an EmployeeEmployee has UnderlingsSlide71

Associations

Associations define relationships between classesNHibernate uses the association mappings to automatically store and retrieve related objects<one-to-one> – file has one owner

<one-to-many> – directory has many files

<many-to-one> – sub-directory has one parent directory (many sub-directories, one parent)

<many-to-many> – Many users, many roles  intersection of a user and a roleSlide72

<many-to-one>, <one-to-many>

<joined-subclass name="NHibernateResearch.Business.Employee, NHibernateResearch.Business" table="Employee">

<key column="EmployeeId"/>

<property name="Title" not-null="true" />

<many-to-one name="Supervisor" column="SupervisorId" not-null="false" cascade="save-update”></many-to-one>

<bag name="Underlings" lazy="true" inverse="true" cascade="save-update">

<key column="SupervisorId"></key>

<one-to-many

class="NHibernateResearch.Business.Employee, NHibernateResearch.Business“

/>

</bag>

</joined-subclass>

SupervisorId is a foreign-key to the supervisor’s EmployeeId

Many-to-one turns the SupervisorId into an instance of Employee

not-null=“false” means that the SupervisorId is nullable

cascade=“save-update” tells NHibernate to check the many-to-one relationship for changes when an INSERT or UPDATE is requested

The association syntax is also used to populate collections of objects

<bag> populates an IList of Employee objects for the current employee

select * from employee where supervisorId=@currentEmployeeIdSlide73

Collections

Mapping Element

Interface

Implementation

Description

<list>

IList

ArrayList

Ordered collection

<bag>

IList

ArrayList

Unordered collection, allows duplicates

<map>

IDictionary

Hashtable

Dictionary (key/value pairs)

Use associations to store collections of reference types

<one-to-many>, <many-to-many>

Use <element> tag to store collections of value types

Similar syntax to <property>Slide74

Collections: <bag>

Collection of objects

<bag name="Children" lazy="true" cascade="all">

<key column="ParentId"></key>

<one-to-many class="classname"></one-to-many></bag>Collection of values

<bag name="Children" lazy="true" cascade="all">

<key column="ParentId"></key>

<element column=“

columnName

“ type="System.Int32"/>

</bag>

System.Collections.IList

If collection of values, allows duplicates

If collection of objects, duplicates get eaten

By default, items in the collection

same order as they in the tables

“order-by” attribute available to do database sorts on dataSlide75

Collections: <list>

<list name="Children" lazy="true" cascade="all">

<key column="ParentId"></key>

<index column="indexValue"></index> <one-to-many class=“classname

" ></one-to-many>

</list>

System.Collections.IList

Uses an numeric, zero-based index column for sorting

Missing index values become null

child0.Index = 0;

// no child with Index of 1

child1.Index = 2;

parent.Children.Add(child0);

parent.Children.Add(child1);

session.Save(parent);

// reload the parent

parent.Children[0]

 child0;

parent.Children[1]  null;

parent.Children[2]  child1;Slide76

Collections: <map>

<map name="Children" cascade="all"> <key column="ParentId"></key>

<index column="indexval" type="System.Int32"></index>

<one-to-many class="

classname" /></map>System.Collections.IDictionary

Unsorted collection uses Hashtable

Collection of key/value pairs

Use <index> for a value type key

Use <index-many-to-many> for an object key

<index-many-to-many column="ItemId"

class="

classname

" />

If sorted, collection uses SortedList

“order-by” attribute available to do database sorts on data

“sort” attribute for sorting using an implementation of IComparerSlide77

Collections

Lazy loading lazy = “true”Expose collections interface not concrete class

ArrayList

 IList

Hashtable  IDictionaryLazy-load proxy loads on first access“inverse” attribute for bi-directionality“child” has a reference back to the parentEmployee has SupervisorSupervisor has Employees“cascade” attributeSlide78

The “cascade” attribute

Controls when changes to child objects are savedOptions:“none” – no cascading saves/deletes“save-update” – cascade for INSERTs and UPDATEs“delete” – cascade on DELETEs only

“all” – cascade on INSERT, UPDATE, DELETE

“all-delete-orphan” – same as all, automatically delete any child objects when the parent’s collectionSlide79

NHibernate, Collections, and Generics

Current release is NHibernate 1.2.1Now supports genericsSlide80

Nullable Columns & ValueTypes

Nullable columns should be avoided even if you don’t use NHibernateSometimes you need themSometimes you’re stuck with them (legacy databases)Under .NET 2.0 – Use the “?” syntax for the nullable properties on your classesSlide81

Auditing Info

Auditing info common to all tables / classesCreateDate, CreatedByLastModified, LastModifiedByBase class functionalityHow to know when to update the values?Slide82

ILifecycle

Allows class to perform actions at certain times during the NHibernate “lifecycle” of the instanceOnSave(), OnUpdate

(),

OnDelete

(), OnLoad()Slightly “pollutes” object model with NHibernate specific codeNow is deprecated  IInterceptorSlide83

Code Demo

Refactor Person to extend BusinessBaseImplement auditing on PersonSlide84

Intellisense for NHibernate

Eliminate the tediumEliminate the potential errorsLearn what else is in there

Download the source

Schemas in “src\NHibernate”

nhibernate-configuration-2.0.xsdnhibernate-mapping-2.0.xsdnhibernate-generic.xsdCopy to Visual Studio’s “Schemas” directory“c:\program files\Microsoft Visual Studio 8\Xml\Schemas”Restart Visual StudioSlide85

Contains(), Evict(), Lock(), Refresh()

Methods on NHibernate SessionContains(object) – Queries the session to determine if it is managing the supplied objectIs the object persistent for the session

Evict(object) – Remove an object from the session’s control

Lock(object, LockMode) – Request that the object becomes persistent for the session

Refresh(object) – Update the object with the current data from the databaseSlide86

“assembly” & “namespace”

Attributes on <hibernate-mapping>Specifies default

Assembly name

Namespace

This name="Com.Benday.ContentManagement.Business.DomainModel.Folder, Com.Benday.ContentManagement.Business”  name=“Folder”Slide87

Simplify Data Access With Generics

Persistent objects operations are almost identicalISession  Save(), Get(), Delete()ICriteria

 GetBy***()

Leads to code duplication in your façade (aka Factory, Finder, Data Access) classes

Use .NET 2.0 generics to SimplifyGain compile-time type safetySlide88

Code Walkthrough

Com.Benday.NHibernateBusinessFacade<>Slide89

Mapping: <query>

Allows you to write HQL complex queries and store it separately from the code Assigned a unique nameAccessed through ISession.GetNamedQuery()

Executed via IQuery.List()Slide90

Mapping: <sql-query>

Write SQL queries against the native databaseStill brings back persistent objectsISession.GetNamedQuery(), IQuery.List()

<return class=“

classname

” alias=“table alias” />Table alias must be in “{ }”Slide91

Design Strategies

Model to schemaCreate the object model first, then create mappingsHave NHibernate generate the database schema

Allows you to be much more database independent

Concentrate on creating a good object model and less about storage

This is the best to start learning NHibernate-Write some code, write some mappings -Export the schema through NHibernate-Look at the database tables and FK relationships and see if it’s what you expectedSchema to modelDatabase first, then classes, then mappingsLegacy development

More difficult, more about the needs of the database and less focus on the object modelSlide92

Create Database Using SchemaExport

NHibernate.Tool.hbm2ddl namespaceReads hbm’s and classes  creates database schema

Reads the database dialect

generates for your db (MySql, Sql Server, Oracle, etc etc) public static void ExportSchema(){ Configuration config = new Configuration();

config.Configure();

SchemaExport exporter = new SchemaExport(config);

exporter.Drop(true, true);

exporter.Create(true, true);

}

Great for unit testing

always have a clean db

db model always in sync with the hbm’sSlide93

Code Demo

Use BusinessFacade<> Use schema export from unit testsCreate an fixture base classCreate a

PersonFixture

Create a Person class

Play around with [TestInitialize] & [TestCleanup]Slide94

Mappings: Create a UNIQUE database constraint

“unique-key” attribute on the <column> mappingSet the same value on all properties that should participate in the keySlide95

Benjamin Day

Consultant, TrainerArchitecture, Development, Project CoachingMicrosoft VSTS Customer Advisory CouncilMVP for C#

Leader of

Beantown

.NET User GroupVSLive, O’Reilly ConferencesTeam System, Team Foundation Server, NHibernate, C#, ASP.NET, TDD, WCFhttp://blog.benday.combenday@benday.com