Feature Builder Contrib

Feature Builder Contrib

Just to call out that Edward Bakkeris coordinating a new Contrib project for Feature Builder. This project provides more feature extensions such as Value Providers and Commands that can be added to an FB project. We are going to start looking into using Feature Builder for the next version of WSCF Blue. If you are […]

Using EF “Code First” with an Existing Database

Using EF “Code First” with an Existing Database

Last month I blogged about the new Entity Framework 4 “code first” development option.  EF “code-first” enables a pretty sweet code-centric development workflow for working with data.  It enables you to:

  • Work with data without ever having to open a designer or define an XML mapping file
  • Define model objects by simply writing “plain old classes” with no base classes required
  • Use a “convention over configuration” approach that enables database persistence without explicitly configuring anything

In my initial blog post I introduced EF “code-first” and demonstrated how to use the default EF4 mapping conventions to create a new database.  These default conventions work very well for new applications, and enable you to avoid having to explicitly configure anything in order to map classes to/from a database.  I then did a second custom database schema mapping blog post that discussed how you can override the default persistence mapping rules, and enable custom database schemas.

In today’s blog post I’m going to cover a question that several people asked me recently, which is: “how do I use EF code-first with an existing database?”

Using EF Code-First with an Existing Database

EF “Code First” works great with existing databases, and enables a very nice code-centric development approach with them. In particular, it enables you to use clean “plain old classes” (aka POCO) for your model objects, and cleanly map them to/from the database using either the default mapping conventions or by overriding them with custom schema mapping rules

Below are step by step instructions on how you can use EF “Code First” with an existing database.

Step 1: Create a new ASP.NET Web Application Project

Let’s begin by creating a new ASP.NET Web Application Project.  My previous two EF “code first” blog posts used ASP.NET MVC – for this blog post I’ll use ASP.NET Web Forms.  Note that all of the EF concepts are identical regardless of whichever type of ASP.NET application you use.

We’ll use “File->New Project” within VS 2010 (or the free Visual Web Developer 2010 Express) and choose the “ASP.NET Web application” project template to create the new application. 

The new “ASP.NET Web Application” project in VS 2010 is a nice starter template that provides a default master-page layout with CSS design (I blogged about this new starter project template in a previous blog post).  When it is created you’ll find it contains a few default files within it:

image

We don’t need these default files (we could instead just use the “Empty ASP.NET Web Application” project template) – but they’ll make our simple app look a little prettier by default so we’ll use them.

Step 2: Reference the EF Code First Assembly

Our next step will be to add a reference to the EF Code First library to our project.  Right click on the “references” node within the Solution Explorer and choose “Add Reference”. 

You’ll reference the “Microsoft.Data.Entity.Ctp.dll” assembly that is installed within the “\Program Files\Microsoft ADO.NET Entity Framework Feature CTP4\Binaries\” directory when you download and install the EF Code First library.  After adding this reference you’ll see it show up in your project’s references window like below:

image

Step 3: Northwind Database

You can skip this step if you have a SQL Server database with Northwind (or another database) installed. 

If you don’t have Northwind already installed then you can download it here.  You can either use the .SQL files it includes to install it into a SQL database, or copy the Northwind.mdf SQL Express file into the \App_Data directory of your application:

image

Step 4: Create our Model Layer

Now we’ll write our model classes and use EF “code first” to map them to our Northwind database.  Below is all of the code we need to write to enable this – no other code is required:

image

Below are some details about what all this code does and how it works:

POCO Model Classes

EF “code first” enables us to use “plain old CLR objects” (aka POCO) to represent entities within a database.  This means that we do not have to derive our model classes from a base class, nor implement any interfaces or attributes on them.  This enables us to keep our model classes clean and “persistence ignorant”.

Above we’ve defined two POCO classes – “Product” and “Category” – that we’ll use to represent the “Products” and “Categories” tables within our Northwind database.  The properties on these two classes map to columns within the tables.  Each instance of a Product or Category class represents a row within the respective database tables.

Nullable Columns

Notice that some of the properties within the “Product” class are defined as nullable (this is what Decimal? means – that indicates it is a nullable type).  Nullable columns within a database table should be represented within the model class as Nullable properties if they are value types:

image

You can also optionally omit specifying nullable columns entirely from a model class if you don’t need to access it.  For example, the Product table within Northwind has a “QuantityPerUnit” column that is a nullable nvarchar, and a “UnitsOnOrder” column that is a nullable smallint.  I’ve omitted both of these properties from the “Product” class I defined above.  Because they are nullable within the database I can still retrieve, insert, update and delete Products without problems.

Association Properties and Lazy Loading

EF “code-first” makes it easy to take advantage of primary-key/foreign-key relationships within the database, and expose properties on our model classes that enable us to traverse between model classes using them.

Above we exposed a “Category” property on our Product class, and a “Products” property on our Category class.  Accessing these properties enables us to use the PK/FK relationship between the two tables to retrieve back model instances.  Notice how the properties themselves are still “POCO” properties and do not require us to use any EF-specific collection type to define them.

Association properties that are marked as “virtual” will by default be lazy-loaded. What this means is that if you retrieve a Product entity, its Category information will not be retrieved from the database until you access its Category property (or unless you explicitly indicate that the Category data should be retrieved when you write your LINQ query to retrieve the Product object). 

EF Context Class

Once we’ve created our “Product” and “Category” POCO classes, we used EF “code first” to create a “context” class that we can use to map our POCO model classes to/from tables within the database:

image

The “Northwind” class above is the context class we are using to map our Product and Category classes to/from the database.  It derives from the DbContext base class provided by EF “code-first”, and exposes two properties that correspond to tables within our database.  For this sample we are using the default “convention over configuration” based mapping rules to define how the classes should map to/from the database. 

We could alternatively override the “OnModelCreating” method and specify custom mapping rules if we wanted the object model of our model classes to look differently than our database schema.  My previous blog EF “code first” post covers how to do this.

Step 5: Configuring our Database Connection String

We’ve written all of the code we need to write to define our model layer.  Our last step before we use it will be to setup a connection-string that connects it with our database.

In my initial EF “code first” blog post I discussed a cool option that EF “code first” provides that allows you to have it auto-create/recreate your database schema for you.  This is a option that can be particularly useful for green-field development scenarios – since it allows you to focus on your model layer early in the project without having to spend time on updating your database schema after each model change.

Importantly, though, the auto-create database option is just an option – it is definitely not required.  If you point your connection-string at an existing database then EF “code first” will not try and create one automatically. The auto-recreate option also won’t be enabled unless you explicitly want EF to do this – so you don’t need to worry about it dropping and recreating your database unless you’ve explicitly indicated you want it to do so.

For this blog post we will not auto-create the database.  Instead, we’ll point at the existing Northwind database we already have.  To do this we’ll add a “Northwind” connection-string to our web.config file like so:

  <connectionStrings>
     
    <add name="Northwind"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\northwind.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />

  </connectionStrings>

EF “code first” uses a convention where context classes by default look for a connection-string that has the same name as the context class.  Because our context class is called “Northwind” it by default looks for a “Northwind” connection-string to use.  Above our Northwind connection-string is configured to use a local SQL Express database.  You can alternatively point it at a remote SQL Server.

Step 6: Using our Model Classes

Let’s now write a (very) simple page that uses our Northwind model classes to display some data from our database. 

We’ll begin by adding a new page to our ASP.NET project.  Right-click on the web project and choose Add->New Item, then select the “Web Form using Master Page” item template.  We’ll name the page “Products.aspx” and have it use the “Site.master” master-page that is included by default with the ASP.NET Web Project starter template.

We’ll add a <asp:GridView> control to our new Products.aspx page.  We’ll configure it to show just the name and price of our Products:

image

Within our code-behind file we can then write the following LINQ query against our model classes to retrieve all active products from our database, and bind them to the above GridView control: 

image 

And now when we run the project and navigate to the Products.aspx page we’ll get a listing of our Products like so:

image

We now have a simple application that uses EF “code first” against an existing database. 

Download Sample

You can download a completed version of the above sample here.  It assumes you have EF “code first” CTP4 and SQL Express installed.

Additional Code Examples

Below are some additional code examples that demonstrate how we could use our Northwind model for other common scenarios.

Query Across Relations

The LINQ query below demonstrates retrieve a sequence of Product objects based on the name of the Category they belong to. Notice below how we can write LINQ queries that span both the Product and a sub-property of its associated Category object.  The actual filter is all done in the database engine itself – so only Product objects get returned to the middle tier (making it efficient):

image

Use the Find method to retrieve a single Product

In addition to allowing you to write LINQ queries, EF “Code First” also supports a “Find()” method on DbSet<T> collections that allows you to write code like below to retrieve a single instance based on its ID:

image

Inserting a New Category

The code below demonstrates how to add a new Category to the Database:

image

Notice how we create the Category object, assign properties to it, then add it to the Context’s Categories collection.  We then call SaveChanges() on the context to persist updates to the database.

Inserting a New Category and Product (and associating them)

The code below demonstrates how to create a new Category and a new Product, associate the Product so that it belongs to the new Category, and then save both to the Database:

image

Notice above how we are able to have the new Product reference the newly created Category by assigning its “Category” property to point to the Category instance.  We do not need to explicitly set the CategoryID foreign key property – this will be done automatically for us when we persist the changes to the database.

EF uses an pattern called “unit of work” – which means that it can track multiple changes to a context, and then when “SaveChanges()” is called it can persist all of them together in a single atomic transaction (which means all the changes succeed or none of them do).  This makes it easier to ensure that your database can’t be left in an inconsistent state – where some changes are applied and others aren’t. 

In the code snippet above both the Category and the Product will both be persisted, or neither of them will (and an exception will be raised).

Update a Product and Save it Back

The code below demonstrates how to retrieve and update a Product, and then save it back to the database.  Earlier I demonstrated how to use the Find() method to retrieve a product based on its ProductID.  Below we are using a LINQ query to retrieve a specific product based on its ProductName.

image

We could make any number of changes (to any existing objects, as well as add new ones).  When we call SaveChanges() they will all be persisted in a single transaction back to the database.

Default Conventions vs. Custom Mapping Rules

When we created the Product and Category classes earlier, we used the default conventions in EF “Code-First” to map the classes to/from the database.  This avoided the need for us to specify any custom mapping rules, and kept our code really concise.

There will definitely be times when you don’t like the shape of the database your are mapping, though, and want to have your model’s object model be different.  Refer back to my Custom Database Schema Mapping blog post for examples of how to use EF to specify custom mapping rules.  These all work equally well when mapping existing databases.

Summary

I’m pretty excited about the EF "Code-First” functionality and think it provides a pretty nice code-centric way to work with data.  It brings with it a lot of productivity, as well as a lot of power.  In particular I like it because it helps keep code really clean, maintainable, and allows you to do a lot concisely.  Hopefully these last three blog posts about it provides a glimpse of some of the possibilities it provides – both for new and existing databases.

You can download the CTP4 release of EF Code-First here.  To learn even more about “EF Code-First” check out these blog posts by the ADO.NET team:

Hope this helps,

Scott

P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

LINQ-ed Lists

LINQ-ed Lists

If you’re still staying on the fringes of LINQ (quite like me ) , here’s something I found that got me liking it quite a bit more and maybe it will do the same for you. I like LINQ in small doses.I’ve seen horrible complex expressions that I would never understand even if i lived […]

Unattented installation of BizTalk & installation path

BizTalk can be installed using command line such as this:

Setup.exe /quiet /addlocal all /IGNOREDEPENDENCIES /INSTALLDIR D:\program files\Microsoft BizTalk Server 2010 /s D:\Install\biztalk2010/configBiztalk2010.xml

But we had an issue with the INSTALLDIR flag. Using the above path, the installation was failing with an error “Unable to load xml file: c:\users\insUser\AppData\Local\Temp\EBZ39051.tmp\1033\Autorun.xml”

After quite a lot of investigation the developer realised that the INSTALLDIR path with spaces in the name was the culprit. Instead, the path should be its DOS short name. In order to do that, do the following:

1) Create the destination folder using the commande MKDIR on the destination drive
2) Get the DOS path using the command DIR /X from the destination drive
3) Run again using now the command such as in this example using the new path: “Setup.exe /quiet /addlocal all /IGNOREDEPENDENCIES /INSTALLDIR D:\PROGRA~2\MICROS~2\ /s D:\Install\biztalk2010/configBiztalk2010.xml”. It should work fine!

Vincent Rouet, CODit

Update on My Upcoming Book – Applied Architecture Patterns on the Microsoft Platform

Looking back at some of my past blog posts, I realized it has been a long time since my last post.  Wow – over 10 months to be exact.  Let me give a little re-cap of what I have been doing in those 10 months.

  • Went to India twice
  • Went to United Arab Emirates twice
  • Went on a month long trip to Australia and New Zealand
  • Went on a weeklong trip to Thailand
  • Visited London, Spain, Germany, Japan, Hungary, Hong Kong, China, and Greece
  • Launched two major eCommerce Websites and numerous major marketing sites (working on the backend BizTalk pieces of course)
  • Worked countless 80+ hour weeks
  • Completed my first book

Yes you read the list correct!  From the person who brings you grammar and spelling error-filled blog posts, I am pleased to announce I was a co-author of a book along with four others (Richard Seroter, Ewan Fairweather, Rama Ramani, and Mike Sexton).  The book is called “Applied Architecture Patterns on the Microsoft Platform” published by Packt Publishing.

This book covers 13 Enterprise scenarios like Remote Message Broadcasting and Multiple Master Synchronization.  For each scenario we review various Microsoft Technologies that can be used to solve the problem.  We analyze the scenario based on a defined set of business requirements and a decision framework to arrive at one final architecture.  That final architecture is outlined step-by-step and sample code is provided.  The book also contains a brief primer on covered technologies.

This book shows the following technologies in a real-life scenario: Windows Azure Platform, Windows Azure platform AppFabric, Windows Server AppFabric – Caching (Velocity), Windows Server AppFabric – Service & Workflow Management (Dublin), StreamInsight, SQL, BizTalk Server 2010 (including the Service Bus), .Net 4.0 Workflow Services, and more.

We have set up a website dedicated to the book: http://appliedarchitecturepatterns.com/

Be one of the first to get the book by Pre-Ordering the book now at Amazon or directly from Packt. Packt has both a paper copy and eBook available with free shipping to numerous countries. 

Look for more to come on my blog about the book, the chapters I worked on, how to download sample code (although it will not be very useful without the book), and videos of the scenarios I worked on.

bLogical Sftp Adapter – New release 1.3.6 available on CodePlex

I got great feedback from many users, and have made some updates to the bLogical adapter:

Disabling the connection pool (only used for send ports)

Some SSH servers can not handle the connection pool very well. This can also be a problem if there is a limit set to number of connections a certain user can have. So I’ve been asked for the possibility to disable the connection pool for send ports, and this can now be done by setting the SSH Connection Limit to "0" in the admin console or BTSNTSvc.exe.config.

Logging and tracing

A much more verbose tracing as been added. If you care to save the trace info to file, you can use the TraceListener (System.Diagnostics):

  1. Enable Tracing in the port configuration.
  2. Open the BTSNTSvc.exe.config (or BTSNTSvc64.exe.config) file and add the following in the Config section:
    <system.diagnostics>
    <trace autoflush="false" indentsize="4">
    <listeners>
    <add name="BTSListener"
    type="System.Diagnostics.TextWriterTraceListener"
    initializeData="bLogical.Shared.Adapters.Sftp.log" />
    <remove name="Default" />
    </listeners>
    </trace>
    </system.diagnostics>

Public key authentication

There was a problem using identity file authentication as the password was sent as an empty string. This works for some but not all servers. The new version always set the password to null, which should work for all servers.

Macros

%UniversalDateTime% added to the list of supported macros

Misc

  • temp folder and remote permissions no longer required properties.
  • Empty files are no longer picked up or processed.

 

Special thanks to John Vestal at CSC and Antti.

Download the adapter from CodePlex