CodeProject
Welcome to this multi-part series about the managed version of theWindows Azure Mobile Services backend. This series is meant for developers who already created an existing WAMS service using the JavaScript backend or for developers who want to start to develop a WAMS service using the managed backend right from the start. In this part I will compare both backends and point out some of the key differences and skills needed. This part is also about the most basic things you need to know about the Microsoft Entity Framework, demonstrating the different scenarios like code-first, database-first etc. .
Recently the the managed version of the Azure Mobile Services backend created lot’s of buzz and earned big acceptance by the developer community.
Developers where eagerly waiting for a managed backend and the people behind Azure Mobile Services worked hard and fast to release the preview as soon as possible.
Many developers however seem to have substantial problems adapting their existing knowledge ( and I am not talking about Web API veterans here) of the JavaScript based backend to the .NET backend.
The new managed backend gives you way more power, but that means also way more responsibility. Not only that, you need to update your knowledge (or even learn from scratch) about Web API, self hosting, dependency injection, Entity Framework and more.
Must haves
In order to use the managed backend you need to make yourself familiar with the following technologies:
- Web API, self hosting and OWIN
- Entity Framework (ORM) and Code First Migrations
- Other related concepts around those technologies
- Azure Service Bus Notification Hubs
Key Differences between the managed and JavaScript backend
- You have to define your tables and your data-model using code first classes
- Your complete API is implemented using custom or specialized Web API 2 controllers and actions (Actions are controller methods)
- You have to define the access permissions for controllers and methods on your own
- Changes to your data-model have to be propagated using Entity Framework Code First Migrations
- You can extend your service and customize the OWIN configuration using dependency injection
- The default way to send out push notifications is done using Notification hubs.
Differences within the Azure Management Portal
The previously mentioned differences can be visualized by comparing both Azure Management Portal entries for the JavaScript and the managed backend.
Everything that can be done in both backends is marked green. The features only present in the JavaScript backend are marked red and the features present in both backends (but with different sub-features) are marked with a pink, filled rectangle. This should give you a quick overview about the changes within the Azure Management Portal.
When it comes to push-notifications and Notification Hubs, the managed backend creates the corresponding notification hub during the creation of your Azure Mobile Service:
Whereas the JavaScript backend needs your approval to enable the “Enhanced Push” feature:
The portal will ask you if you are really serious and will point out that you should read the documentation in order to master the changed behavior of your push-object methods in your scripts. If you confirm, you will see the same Notification Hub configuration page that is available for a managed backend:
You can see that the name of the notification hub was given the same name as your mobile service.
Mobile Services Data (JavaScript Backend) Tables, Permissions and CRUD-Operations
To perform certain actions based on CRUD operations on Azure SQL tables you can create tables directly using the JavaScript backend:
You can see clearly as well, that the permissions for all CRUD operations (Insert, update, delete and read) can be directly set within a handy dialog.
After adding the table and setting the default permissions (that can be changed later using the “Permission” entry within the portal) you are ready to implement the different CRUD operations using the portal or Visual Studio:
You can open the files attached to each table in your JavaScript backend using the Server Explorer in Visual Studio and connecting to your Azure subscription. When that is done, simply expand the “Mobile Services” entry and expand your Mobile Service. Beneath each table you can find the scripts according to each CRUD operation.
That’s the place where you define what happens for example when you add new records to your table, like sending out push-notifications, saving user credentials etc. Simply double click the desired file and it will open within Visual Studio. How cool is that? Now you can enjoy the full comfort of Visual Studio! You can see also that the custom API-Scripts are not attached to a table. That indicates that those scripts can be used on a broader base.
That’s awesome, but how does it compare to a managed version of a Mobile Service?
Preparing the Notification Hub
When you create your managed backend using the Azure Management Portal, the system will automatically create a new Notification Hub ready to use for your service. You only need to set the package-sid and the client secret within the push settings of your managed backend as well as for the associated Notification Hub.
You can find this settings within the Microsoft account Developer Center. If you go to your developer dashboard (Windows Store Dev Center) and edit your app, you click on the left on Services and then on Live Services Site on the right. This will open the right page where you can copy the package-sid and client-secret from.
Mobile Services Data (Managed Backend), Tables,Permissions and CRUD-Operations
I think it is easier to demonstrate this using a step-by-step approach. Before you even open Visual Studio to create a new managed service I strongly recommend you, to upgrade to the latest Azure SDK available. At the time of this writing it was Version 2.3.
Fire-up Visual Studio and create a new Project. Select the Cloud entry and choose the Windows Azure Mobile Service template.
After you hit ok the New ASP ,NET Project Wizard shows up. Select Azure Mobile Service and hit Ok.
Visual Studio will now create the managed backend service. This takes a few seconds. If we take a look now at the complete structure of the project we can map that to a JavaScript backend like this (this terms are technically NOT correct, but will help to build a first bridge between the JS and Managed backend):
- App_Start folder: This folder contains the WebApiConfig.cs file. This file is used to set the Web API configuration options and to initialize the Entity Framework DbContext. More on that one later.
- Controllers folder: This folder contains the controllers needed to perform the CRUD-Operations on your data-tables. They are not derived ApiController (later more on that one) class but from the TableController<T> class where T needs to be a class implementing the ITableData interface (those classes can be found within the DataObjects folder)
- DataObjects folder: This folder contains the classes that represent your tables. Each of the classes placed there represents exactly one table and each class is derived from EntityData, which implements, you got it – ITableData
- Models folder: This folder contains the Entity Framework data-context that represents your database-structure. You can actually think of it as your database. It implements basic patterns like the repository-pattern and the unit-of-work pattern. In short: It maps your model-classes (within the DataObjects-folder) directly to the tables within your database. And of course, it creates those tables based on your model-classes. More on that later.
- ScheduledJobs: This folder contains classes that derive from the ScheduledJob class. You can execute those jobs also manually, or your can create your job-class and set the scheduling parameters later on the portal, entering the name of your job-class (without the “Job” part, in the screenshot it would be “Sample”) and schedule it that way
- The Global.asax file is the ASP .NET application file. It’s used to work with application-level events, like a the Application_Start event when an ASP .NET application is started. Those are global events that are not bound to specific users, but to the app, the “core” itself. It derives from the System.Web.HttpApplicationClass.
- The web.config file can be compared with a app.config file, only for webservers. It contains assembly references, database connection-strings, service-bus connection strings, other configuration sections like the section used for the Entity Framework
Entity Framework Basics
You data is the most important part of the Mobile Service. If you never used or worked with the Entity Framework before, this section is for you. If you are already familiar with the Entity Framework and its workflows using the Code-First approach as well as Code-First Migrations you can skip this section.
Over-Simplified managed backend-architecture diagram in relation to the Entity Framework:
What is Entity Framework ?
The Microsoft Entity Framework is a so called ORM, or Object Relational Mapper. In a very simple form the ORM maps your classes (also called domain-specific objects) to database-tables. Those tables don’t have to exists physically within the database, which is the Code-First approach. If the tables already exist and you reverse-engineer the database to domain-specific objects, this approach is called then database-first.
Both methods, Model-First and Code-First come in two flavors:
- You can create a new database using code or a designer
- Or you can use an existing database using code or a designer
To test all of the four options you can download the Microsoft SQL-Server sample database Adventure Works. Using this database, you can test already two of the four variations (db-first-code and db-first-model):
If you have a local instance of SQL-Server Express or any other version of SQL-Server, like the SQL-Server developer edition, you can download the Adventure Works sample database here and attach the database files using SQL Server Management Studio or the installer version for your version of SQL-Server (2005, 2008, 2012 or 2014).
Testing the four variations using simple console projects
Open Visual Studio and create a new empty solution. Name it “EFVariationTests” or whatever you like to name it and add four console projects to the solution:
- DBCodeFrist
- DBFirstDesigner
- DBFirstCode
- DBModelFirst
If you have not installed the Adventure Works database, you can use of course any other database as well.
Now right-click the project “DBCodeFirst” and add a new item. Name the item “CodeFirstTest” and click “Add”.
On the right hand side choose “Data” and select “ADO .NET Entity Data Model” on the left. Click add and the “Entity Data Model Wizard” will pop-up. Within the wizard select “Empty Code First model”. This will create a code first-model that later on can be converted into a database including the tables on your SQL-Server.
Press “Next” to put the wizard to work. The wizard will add all necessary assemblies (EF Framework) and generates on C# file (CodeFirstTest.cs in my case) and will set the base database-connection string within app.config. If you have an existing database you want to create the tables for, you can use “Server Explorer” to connect to your local or external SQL-Server instance. When you right-click the database within the “Server Explorer” and choose properties, you can simply copy the connection string for your database and paste that into app.config:
- The generated DBContext class
- app.config containing the connection string. Simply replace the “connectionString” attribute-value
- “Server Explorer” with selected database
- Database properties and the connection string that can be used. Otherwise a localDB file will be created
Now that we have everything in place to use our “CodeFirst” approach, we can create a new table, simply by adding a new class. In real-world projects you would add an additional “Model” folder to your project and move the generated C# into this folder, as well as your domain-specific classes. But for the sake of simplicity, we add a new class to the project and name it “Customer”.
The “Customer” class will represent a table within our database. We add three public members (Auto-Implemented properties, no backing fields for the property accessors):
- Id (int) – The primary-key for our table
- FirstName (string)
- LastName (string)
Now we need to tell EF what kind of column’s to create when the table is created. Entity Framework offers handy attributes that are called “Code First Data Annotations”. You can read more about CFDA here.
To identify the “Id” member as the primary key, we us the [Key] attribute. Additionally we pin the [DatabaseGenerated(DatabaseGeneratedOption.Identitiy)] attribute on the “Id” member to tell EF to generate a unique key that is automatically incremented each time we insert a record into the table.
The “FirstName” and “LastName” members have both the [Required] attribute and the [Column(“columname”, TypeName=”sqlservertype”)] attribute pinned on them. This means that both members need to contain a value when we insert a new record or update it (we cannot set their values to null). Both members have the TypeName property of the Column-Attribute set to the nvarchar SQL-Server type (Unicode-Based characters). The length will be set to MAX in this case. When EF runs the queries against SQL-Server (the create table … statement), it will re-name the columns to the values passed as first parameter to the Column-Attirbute (“firstname”,”lastname”). On top of our Customer class we have placed the Table-Attribute to indicate which table-name to use when the table is actually created within our SQL-Server database.
Now we need to create what’s called a dbset and extend our “CodeFirstTest” class that derives from DBContext. Open the EF generated class file, in my case “CodeFirstTest.cs” and add a new property of type DbSet<Customer>, make it virtual and public and a Auto-Implemented property. Virtual because EF will manage change tracking and lazy loading, by overriding this member.
Now one last step is required to actually push the required changes to our database: We need to enable code-first migrations. Code-First migrations allow you to update the database according to your current changes. For example if you add more members, remove members or change attributes on our Customer-Class. They work down and upwards. Upwards means the current changes of a specific migration will be applied or (downwards) means we roll-back to the applied changes of the current migration.
Code-Frist Migrations are enabled per Project using the NuGet-PackageManager console. Open the NuGet Package-Manager console and type in the following command:
Enable-Migrations
You can see that my first attempt failed because I messed up the connection string, when I now try to run the command again, I get another error message, that migrations have been already enabled. You can see that the command added a new folder to our project named “Migrations” containing a file named configuration. I run the command again, this time with the –Force parameter. This will instruct the command to overwrite the existing migration configuration. And this time it worked, a new Configuration.cs file was created within the “Migrations” folder.
The Configuration class is derived from the DbMigrationsConfiguration<DBCodeFirst.CodeFirstTest> class using our database-context (DBCodeFirst.CodeFirstTest) as a type-parameter. It contains a constructor and a Seed method that has been overridden. Within the constructor the AutomaticMigrationsEnabled property has been set to false, which means that we need to add changes manually by defining our own migrations and then we are able to push changes to the database. If this parameter would be set to true, we just need to push the changes to the database. I prefer to have full control over the process, so I chose not to use automatic migrations.
The Seed method is used to perform any post-migration related things like adding or deleting new records or performing other post-migration related configurations. For now we leave this part as is.
To add our initial changes to the database, we use the following command (again within the NuGet Package Manger Console):
Add-Migration “InitialMigration”
This command will add a new [DateStamp]_[MigrationName].cs file to our “Migrations” folder. Each time we create a new migration a new file will be added with the same format and an entry will be added to the migrations-table that will be automatically created within our database.
The current migration file (like any other migration files) derives from the DbMigration class. You can see two overridden methods in this class “Up” that will actually add the current changes (creating the new table “dbo.customers”) and adding the columns as well as defining the primary key. The Down method on the other hand would roll-back the changes and delete the changes again.
To push the changes actually to the database we use the following command (again within the NuGet Package Manger Console):
Update-Database
Just to show you what is going on under the hood – let’s execute the command using the parameter –Script . This way the actual migration will not be pushed to the server and you can see the T-SQL statements that would be executed if you omit the parameter.
That’s really great. We can see that all of our data-annotations work as expected as well. Let’s now execute Update-Database and omit the –Script parameter. If we take a look at our database, we can see that the migration has been applied successfully to our database.
Open Program.cs and let us add a new record to the customers table. Before we can do that, we need to create an instance of our DBContext derived class. We put that guy into a using-statement to have it cleaned up, after the work is done.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace DBCodeFirst
{
class Program
{
static void Main(string[] args)
{
using (var db = new CodeFirstTest())
{
var customer = new Customer()
{
FirstName = "Greg",
LastName = "Bolton"
};
db.Customers.Add(customer);
db.SaveChanges();
}
}
}
}
Then we create a new Customer instance (note that we do NOT set the Id, this is done by SQL Server) and we add the new customer to our DbSet Customers. Then we tell the DbContext to save the changes. Note that we are currently not using the async implementation of the db.SaveChanges method. But you could and should do that of course in your implementations. Especially when it comes to API’s that could be used by thousands of users.
Code First From an existing database
Let’s now actually see, how the EF Wizard will create all the classes the we need to get up and running with an existing database reverse-engendered to Code First.
This time perform the same steps we used for the Empty Code First model until the Entity Data Model Wizard pops-up again. Then choose “Code First from database”. In the next step the Entity Data Model Wizard will show you the default connection we added in the last project which you could use of course, but I will change the connection and grab some tables from the Adventure Works database. Therefore I click on “New Connection…” In the lower part of the current screen you can see your current connection string and you can specify a name for the connection-string entry in App.config.
When you choose to add a new connection, the connection properties dialog will pop-up. Select your SQL-Server there and the kind of authentication you want to use. In the lower part select the database you want to use. In this case I chose Windows Authentication and the database “Adventure Works 2012”. You can test the connection by clicking “Test Connection”.
The connection string will change and the EF Wizard shows you now the available database-objects that you can choose now to be reverse-engineered to code. As you can see there are multiple schemas available as well as views. I will just select one the HumanResources part here to keep the generated code nice and clean.
And as the code gets generated I get a warning that I am unable to use the HierarchieId (like eid). Let’s try a workaround. There is a package out there that has an HierarchieId implementation, but is NOT an official MS package. I remove the current EF nuget-package version 6.1.0 and install the Entity Framework with HierarchyId package also version 6.1.0 instead using the Package Manger Console. The HierarchyId data-type is very handy to store hierarchical data. You can read more about this built-in SQL-Server data-type here. I would love to see that type finally implemented. But for now, I installed it only to make the demo work. After this change the HierachyId type was there. The model is complete.
All the necessary classes have been created as well as the data-context. Now we can open Program.cs and add a new record into the database. We first create a new db-context object and add a new department.
The new department was added successfully
Empty EF Designer First
This is the first graphically supported method. Visual Studio offers you full-fledged EF designer support, that allows you to create your database-entities using a graphical tool.
Follow all the steps you did before and choose “Empty EF Designer” when the Entity Data Model Wizard pops-up. Use the project DBFirstDesigner to do that.
The wizard will offer immediately the Finish button and you can start to design your database-model.
Grab an entity element from the toolbox and drag it onto the design-surface. As you noticed, the wizard added an .edmx file contains the model as well as the information’s to render the graphical representation of the classes. You can learn more about .edmx files here.
Rename the entity to “Customer” by clicking the name (Entity1). Select the Id column now and take a look at the properties window. You can see now that the Id column was already defined as the Entity Key and the StoreGeneratedPattern was set to Idenity already.
Now right-click the property node, select “Add New=>Scalar Property” . Rename the property to FirstName. Select the FirstName column and change the Type using the properties window to String and Unicode to true. This will create an nvarchar instead of an varchar column. Repeat this steps and add another column “LastName”.
Open the “Server Explorer”, right click the Data Connections node and choose “Create new SQL Server database…”. A new wizard pops-up and you can connect to your SQL Server instance. Type in a name for your new database and hit “Ok”.
Now right-click the designer surface and select “Generate Database from Model….” and change the connection to your newly created database by clicking “New Connection….” Leave the rest as is (Entity Framework 6) and click on “Next”. You will get now a cool piece of generated DDL code (Data Definition Language) you can check and hit finish if everything is ok. After the wizard finished its magic, you will be presented with the T-SQL code that you can run against the database hitting the green play-button right above the generated code.
All the T-SQL code was successfully run against SQL-Server your database should now contain the Customers table.
Time to add new record. Open the Program.cs file and add the code to insert a new customer in our customers table:
I leave the last option up to you. Select the DBModel first project and perform all the steps to add a new Entity Data Model to your project. Within the Wizard select the first option “EF Designer from database” and try to add new data to a table of your choice on your own.
Thanks for reading. In the next part you will learn more about OWIN, Web API, table-controllers as well as custom controllers.