Skip to main content

Entity Framework Code-First: how to generate an auto-increment ID field

I’ve already covered the practical advantage of the code-first approach featured by Entity Framework 6 in a previous post: the key concept there was all about creating the whole data model  starting from some very standard C# classes: namely, the Entities. The most frequent question asked by readers was: how to define an auto-increment Id field (or primary key) of an Entity? In other words, how can we tell the DB to assign an unique, incremental id number to each and every record by its own?

The answer is quite simple, as long as you’re using MySQLMicrosoft SQL or any other Entity Framework compatible DBMS featuring a native auto-incremental numeric fields support: all we can do is to tell the Entity Framework to properly generate it.

In order to do so we just need to use the DatabaseGeneratedAttribute in the following way:

The ID field will then be set as auto-incremental during the DB generation phase, granting a table-unique ID to each Item record.

That’s about it. Happy coding!

 

Configure MySQL to handle camel case (or case sensitive) table names

The default settings provided with the Win32 and Win64 builds of MySQL enforce a strict lowercase conversion for all the table and database names. This feature can be annoying for those working with auto-generated code tools (such as Entity Framework) because all the entities will be created in lower case as well. To overcome that we can use a useful, yet not widely known MySQL system variable who allows us to change the default behavior: lower_case_table_names. It can easily be added to the MySQL my.cfg file, usually found in the following folder:
C:\Program Files (x86)\MySQL\MySQL Server 5.6\
The system variable must be placed under the [mysqld] section, just like that:
Possible values are:

  • 0: Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or  CREATE DATABASE statement. Name comparisons are case sensitive. It’s not advisable to set this variable to 0 if you are running MySQL on a system that has case-insensitive file names (such as Windows or Mac OS X): the official documentation discourages that because there could be issues with MyISAM indexes files.
  • 1: Table names are stored in lowercase on disk and name comparisons are not case sensitive. MySQL converts all table names to lowercase on storage and lookup. This behavior also applies to database names and table aliases. This means that all queries will be case-insensitive regarding db and/or table names (SELECT * FROM STUDENTS e SELECT * FROM students will give the exact same result); on the other side we won’t be able to use uppercase characters at all, which bring us back to our main issue.
  • 2: Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or  CREATE DATABASE statement, but MySQL converts them to lowercase on lookup. Name comparisons are not case sensitive. This works only on file systems that are not case sensitive! InnoDB table names are stored in lowercase, as for lower_case_table_names=1.
For an extensive overview of the lower_case_table_names system variables we suggest to check out the official MySQL documentation:

ASP.NET: Setup a MVC5 website with MySQL, Entity Framework 6 Code-First and VS2013

The new features available in EF6 allow any developer to build a simple DB-powered website with very few lines of code. There are many tutorials explaining how to do that with SQL Express available on the web, but those who want (or are forced) to use MySQL will most likely find a quite smaller amount of literature. I wrote this simple guide for those who asked me to summarize all the required steps to build a MySQL-powered MV5 website using Visual Studio 2013 and Entity Framework 6. For the first steps I’m gonna quote the old good Getting started with Entity Framework 6 Code First using MVC5 available on www.asp.net website, which also holds the credits for the images I used.

Let’s start with a list of everything we’re gonna need (and their free download links):

Step 1. Creating a new Web Application

Let’s start Visual Studio 2013 and create a new C# project just like that:

NP

In the following screen we’re gonna choose the MVC template, then we’re click to the Change Authentication… button where we can choose if we want to enable authentication mechanism or not. The answer here depends on the features we need to have in the website we’re building: for this example we do not need any authentication system, so we can choose No Authentication.

CA

The next steps are kinda obvious, we just have to click a couple OKs to end the web application creation phase.

Step 2. Installing the Entity Framework

From the Tools menu, select Library Package Manager and then Package Manager Console. Insert the following command:

NuGet will automatically download and install the most recent version of the Entity Framework (currently 6.1.1). As soon as the tasks is completed we can start creating our Entities following the code-first approach.

Step 3. Creating the Entity Classes

It’s worth to mention that an Entity isn’t anything more than a class designed to hold all the relevant fields about a single element (i.e. row) of our Database. That’s why before we start creating Entities we definitely need to have a decent idea about what we need and, most importantly, which kind of relationship our elements are gonna have. For this example let’s just flush out an evergreen classic: The Student-Enrollment-Course archive. Here’s what we’re gonna have:

  • a list of Students
  • signing up to zero-or-more Enrollments
  • related to zero-or more Courses

In order to build such a model we need to open the /Models/ folder (creating it if it doesn’t exists) and add the following three classes:

 Step 4. Setting up the Database Context

The main class who handles and keeps track of the various Entity Framework operations is known as Database Context. It can be created by adding a new class, deriving it from System.Data.Entity.DbContext and inserting some properties for all the Entities we just created, who will populate the Data Model. Let’s move to the /DAL/ folder (for Data-Access-Layer), creating it if it doesn’t exist already, and add the following two classes:

We can see that the MyDbContext.cs class contains a DbSet for each Entity we previously created. That’s because in the Entity Framework pattern each DbSet is corresponding to a Database Table, while the Entities are the table records (or rows). We can also see that in the constructor initializer we’re instantiating  an object of type MyDbInitializer, which is defined in the following class: we need this object to initialize the database the first time we launch the application and also to insert some sample record in the newly created Student table. We can derive the MyDbInitializer from a number of initialization base class made available by the framework, such as:

  1. CreateDatabaseIfNotExists: This is the default initialized: as the name suggests, it creates the database if it doesn’t exist already. It’s worth to say that if the DB is already present and it’s Model differs from the one specified by the Entities, this initializer will throw an exception. This behaviour makes it an optimal choice for the production environments  (where you don’t want the DB to be altered by the EF6 automatic tasks) but not-so-great for the development ones (where the Database Model frequently changes).
  2. DropCreateDatabaseIfModelChanges: This initializer creates a new database, deleting the previous one (if any), everytime the DataModel is changed since the last initialization. It’s worth to mention that a DataModel “change” everytime one or more Entity class is added, removed or modified in any way. This is an ideal behavior for development and testing environments, where we usually want to reset/update the DB every time we need to change the way we want to store data: for these exact same reasons it should never be used in any production environment in order to avoid data-losses (a small change in one Entity class is all it will take to erase all data in the DB).
  3. DropCreateDatabaseAlways: As the name suggests, this initializer deletes and re-creates the DB on every initialization, i.e. every time the web application will start. This might be good for those development (or testing) environments designed to work with the same, pre-defined amount of data every time: needless to say, it’s far from ideal in any production environment.

IMPORTANT NOTE: as stated in this comment, it seems that some Entity Framework builds require to use DropCreateDatabaseAlways instead of CreateDatabaseIfNotExists when using migrations and initializing them for the first time, otherwise the _MigrationHistory table won’t be created and the Seed() method won’t run. As soon as you do that, you can switch to CreateDatabaseIfNotExists or DropCreateDatabaseIfModelChanges and everything will work as intended.

Before going on, notice that MyDbContextConnectionString literal referenced by the constructor initializer of our MyDbContext.cs class: this is the connection string we’ll add to our Web.Config during the next step.

 

Step 5. Connecting to MySQL

To connect our web application to our MySQL database we need the MySQL Connector.NET, which can be downloaded from the official site or using NuGet. All we need to do is to add its libraries to our project and add a valid connection string to our Web.Config file, just like that:

 

Step 6. Running the Application and (auto)creating the Database

If all the previous steps have been properly completed the web application will automatically create the database as soon as an object of type MyDbContext will be instantiated. For example:

You can initialize the object inside a Controller, in a singleton class (or in the Global.asax) as a static property or in other parts of the web application depending on developer needs and/or the choosen design pattern  and/or IoC/UoW strategies you might want to adopt. In the upcoming posts I’ll talk more about these techniques, as well as explain other useful EF concepts, capabilities & tools such as Data Migrations and more.

Close