Follows on from part 1
As part of my investigations into the Entity Framework, I’ve setup a test project as a testbed.
You can download it here: EF Research project. You’ll need the Orcas beta 2 Pro (minimum), The Entity framework beta, and the Entity Framework ctp tools
Project Structure

I created a blank solution and added a class library called EfNorthwindLibrary. In this project, I’ve created a EntityFramework model called CustomersModel.edmx (Right click, add new item, Select ADO.NET Entity Data Model and follow the wizard). For the moment, the Customers model contains only a reference to the Customers table - I will be expanding on this as I go through my posts.
Build Events
If you look at the Build Events of the project (Right click, Properties, Build Events), you will see a Post-build event command line which looks something like “%windir%\ Microsoft.NET\ Framework\v3.5\EdmxDeploy.exe” “$(ProjectDir) ” “$(TargetDir) “ - this tells the project to take the .edmx files contained within the library and output them as csdl, msl and ssdl files into the project output folder. Apparently, this will ultimately become an msbuild task, so it doesn’t need to be a post build event.
App.Config
If you now look in the App.Config, you will see a Connection String entry that looks something like: <add name=”NorthwindCustomersEntities” connectionString= “metadata=.\CustomersModel\CustomersModel.csdl |.\CustomersModel\CustomersModel.ssdl |.\CustomersModel\CustomersModel.msl; provider=System.Data.SqlClient; provider connection string=”Data Source=XPDEV\SQLEXPRESS;Initial Catalog=Northwind; Integrated Security=True” ” providerName=”System.Data.EntityClient” /> This contains three sections: a metadata section, a provider section and a provider connection string section.
The metadata section tells the framework where to find the csdl, msl and ssdl files, the provider section tells the framework which provider to use (this is where you can specify an alternative provider to the SqlClient - once they get written by third parties), and finally the provider connection string is a standard database connection string used by the provider. You can also specify all these settings in code if you prefer, but I’ll come to that another time.
CustomersModel.Designer.cs
You’ll see there is also a CustomersModel.Designer.cs file. If you have a look at it, you’ll see it contains two classes - NorthwindCustomersEntities of type System.Data.Objects.ObjectContext, and Customers of type System.Data.Objects.DataClasses.EntityObject. Both these are generated from the .csdl file.
The context class (NorthwindCustomersEntities) is how your application interacts with the model, and contains a collection of Customers in the form of a System.Data. Objects.ObjectQuery<Customers> property. The constructor for the class takes in a connection string, an EntityConnection object, or nothing, in which case it uses the connection string found in app.config with the same name (”NorthwindCustomersEntities”).
The Customers class represents a single Customer record, and contains the various customer properties (CompanyName, ContactTitle etc…). It’s a bit confusing, but the Customer table in the Northwind database is called Customers (plural, bad design), and the code generation just copies the names. We should be able to make it a singular that in the mapping at a later date.
The above two classes also contain a couple of utility method,
static Customers.CreateCustomers(customerId, companyName) - this returns a new customer instance.
and
NorthwindCustomersEntities.AddToCustomers(customers) - this adds a customer to the context.
These are partial classes, so we can extend them later with our own business logic.
Testing the generated classes and the mapping - Unit Test.
The Visual Studio Test system has made it’s way into the Pro version of Visual Studio 2008, so now I can run tests with the MS test framework, rather than nunit and testdriven.net (not that I don’t like nunit and testdriven.net - I wonder how this decision will affect testdriven.net, as it’s been a great alternative to paying full wack for the top end version of Visual studio).
The Test project is called EF_Test (right click solution, Add New Project, Test Project). We need to add a reference to EfNorthwindLibrary, and references to System.Data and System.Data.Entity.
We can create a new test such as:
[TestMethod]
public void TestConnectionStringWorks()
{
NorthwindCustomersModel.NorthwindCustomersEntities context = null;
context = new NorthwindCustomersModel.NorthwindCustomersEntities();
Assert.IsNotNull(context);
}
Run the test (On the menu, Text > Windows > Test View, and click Run Selection - don’t try to run the project - you can start a class library!)
Now, this will fail. We haven’t passed the NorthwindCustomersEntities a constructor, so it’s going to look in the App.config on the test project to find the connection (and it’s not there). Lets add an app.config to the project, and copy in the connection from EfNorthwindLibrary app.config.
Now it’s still going to fail, because the connection in app.config references the .csdl, .msd and .ssdl files, which our test can’t find. We’re going to have to edit the LocalTestRun.testrunconfig file to tell it to copy the three mapping files output by the EfNorthwindLibrary to the test output folder. We do that by double clicking the solution file LocalTestRun.testrunconfig, goto the deployment option and click Add File - browser to EfNorthwindLibrary\bin\Debug and select the three files we need. Now these three files will get copied to the test output folder.
Finally, make sure the metadata= in the app.config (for the test project) points to the files in the current folder, e.g. metadata=”.\CustomerModel.csdl ….” etc because the original app.config has the .csdl etc files in a subfolder rather than the current folder.
Now run the test - we should get a pass!
Once we have the project at this point, we can start to explore more.
Final note on unit testing
Further to this post^ on the msdn forums - when running unit tests, it should be possible to test business logic without hitting a real database (as this may require the database to be in a known state - a bad thing with unit tests). The usual method is to mock out the data access code. Anyway, that can’t be done at the moment, so I’m working on a “Mock” entity data provider, so that your unit tests would be able to provide the data that the business logic expects to receive. Something like:
- Create a dataset containing known data
- Pass that dataset to the mockEntityProvider
- Test the business logic of a class that querys the mockEntityProvider for the known data
- Verify the results of the business logic.
Watch this space. In the next post, I’ll be delving into the actual file structure and looking at adding an association to another table.