Open Visual Studio and create a new class library project, I’ve named mine EFCodeFirstReporting. Once this project is created, delete Class1.cs. Next we will want to add the Entity Framework 5 package from NuGet.
Now we are ready to define our model. For this example we’ll just keep things simple. We will create a class that represents a Car. Add a new class file to your project and name it Car.cs, and implement it as follows:
using
System;
using
System.Linq;
namespace
EFCodeFirstReporting
{
public
class
Car
{
public
int
CarId {
get
;
set
; }
public
string
Vin {
get
;
set
; }
public
string
Make {
get
;
set
; }
public
string
Model {
get
;
set
; }
public
int
ModelYear {
get
;
set
; }
}
}
In the cases where the database is newly generated, we will want to be able to seed the database with some useful data. To do this, we will need to implement a database initializer. We will extend the default initializer that Entity Framework uses and override its Seed method. Add a new class, name it CarsDbContextSeedInitializer.cs and implement it as follows:
using
System;
using
System.Linq;
using
System.Data.Entity;
namespace
EFCodeFirstReporting
{
public
class
CarsDbContextSeedInitializer : CreateDatabaseIfNotExists<CarsDbContext>
{
protected
override
void
Seed(CarsDbContext context)
{
Car car1 =
new
Car();
car1.Vin =
"54321"
;
car1.Make =
"Toyota"
;
car1.Model =
"Sienna"
;
car1.ModelYear = 2013;
Car car2 =
new
Car();
car2.Vin =
"12345"
;
car2.Make =
"Ford"
;
car2.Model =
"Mustang"
;
car2.ModelYear = 2011;
context.Cars.Add(car1);
context.Cars.Add(car2);
context.SaveChanges();
}
}
}
Our DbContext will contain a series of constructors as well as a DbSet that contains our Car objects. Create a new class, name it CarsDbContext.cs and implement it as follows:
using
System;
using
System.Data.Entity;
using
System.Linq;
namespace
EFCodeFirstReporting
{
public
class
CarsDbContext : DbContext
{
static
CarsDbContext() {
Database.SetInitializer<CarsDbContext>(
new
CarsDbContextSeedInitializer());
}
public
CarsDbContext() :
base
(
"Name=CarsDbContext"
) { }
public
CarsDbContext(
string
conn) :
base
(conn) { }
public
DbSet<Car> Cars {
get
;
set
; }
}
}
The static constructor will ensure that if the database does not exist and needs to be created that it will be initialized with data created in the initializer. The parameterless constructor will default to using a connection string from configuration that bears the same name as our DbContext class (we will be adding this entry in a moment). The third constructor allows a connection string to be passed into the DbContext. This constructor is used by Telerik Reporting to enhance the design time experience of the developer, it allows the correct connection string to be passed in when processing/previewing the report so that the report renders correctly. The last item in this class is a public property that represents a DbSet of our Car objects for Entity Framework to query and track changes.
This is an optional step, by default when Entity Framework Code First generates a database it will use the local SQL Express instance and create a database with same name as the DbContext (fully qualified with namespaces and all). If however you want to have more control over where the database is created and the naming of the database itself, you can create a connection string entry in the configuration file keyed with the same name as your DbContext class. In this case we will be adding a CarsDbContext connection string to the App.config as follows:
<
connectionStrings
>
<
add
name
=
"CarsDbContext"
connectionString
=
"data source=.\SQLEXPRESS;Integrated Security=SSPI;database=CarsDb;"
providerName
=
"System.Data.SqlClient"
/>
</
connectionStrings
>
Build the EFCodeFirstReporting project, and open the bin folder for your build in file explorer. Copy the following files:
You will need to paste them into the executable folder of Telerik Report Designer, located in a path similar to “C:\Program Files (x86)\Telerik\Reporting Q2 2013\Report Designer”. The next thing we will need to do is add a reference to this assembly in the Telerik.ReportDesigner.exe.config file. In the assembly references section of the file, add an entry for our EFCodeFirstReporting as follows:
<!-- Add assembly references -->
<
Telerik.Reporting
>
<
AssemblyReferences
>
<
add
name
=
"EFCodeFirstReporting"
version
=
"1.0.0.0"
culture
=
"neutral"
publicKeyToken
=
"null"
/>
</
AssemblyReferences
>
</
Telerik.Reporting
>
Open Telerik Report Designer and create a new report and exit out of the Wizard. Click on the Data tab and select to add an Entity Data Source. Select the “Specify a new connection string” from the radio button list, and enter your database connection string in the text area.
You can then choose to save the connection string in the Telerik Report Designer configuration settings for later use. Next you will be prompted to select a context for your Entity Data Source, you will see that our referenced assembly and CarsDbContext are available for selection.
In the next screen, select the Cars DbSet, then click Finish:
Next click on the Insert tab. Select the Details section of the report and insert a Table Wizard. In this Wizard, select the Entity Data Source we just created, and click next to define the columns of the table that we want to have displayed, then click Finish.
Save the Report, then click on the Home tab, and click the Preview button. You will see that the report is run and the data that we seeded the database with is displayed in the table.
If you open SQL Management Studio you will see that Entity Framework created the CarsDb database to our model’s specification.
In this blog post we covered how to use Entity Framework with a Code First approach with Telerik Reporting. We included our code first assembly as a reference within Telerik Report Designer and allowed the tooling to initiate the creation and initial seeding of the database. This can come in handy when users work locally on their own machines and later synchronize with a central database. It is important to note that you can also create report libraries in Visual Studio and use the Code First approach by simply adding a reference to the EFCodeFirst project and applying the application configuration values.
Carey Payette is a Senior Software Engineer with Trillium Innovations (a Solliance partner), an ASPInsider, a Progress Ninja, a Microsoft Certified Trainer and a Microsoft Azure MVP. Her primary focus is cloud integration and deployment for the web, mobile, big data, AI, machine learning and IoT spaces. Always eager to learn, she regularly tinkers with various sensors, microcontrollers, programming languages and frameworks. Carey is also a wife and mom to three fabulous boys.