This blog focuses on how to register the DB2 EF6 Provider in modern Entity Framework applications using Code-Based Configuration. It targets an ASP .NET 5 Web Application where we are enforced to use Code-Based Configuration for registering our DB2 EF6 Provider.
CodeConfigDB2EF6Sample project (an ASP.NET 5 MVC application) creates a simple website that accesses data on an IBM Data Server via DB2 EF6 Provider.
The source code for this sample can be downloaded by clicking the following:
Please modify CodeConfigDB2EF6Sample depending on your environment e.g. the connection string in config.json, and tailoring of DbContext (DB2Context.cs), Entity (Employee.cs), and other classes...
Refer to the latest ASP .NET/EF documentation for MS recommended guidelines, and best practices.
DS Driver (64-bit for windows) and VSAI
Go to ASP .NET 5 RC and click on 'Install for Windows'. Follow the Install Instructions.
Tooling/Runtime: Visual Studio 2015 Update2, ASP .NET 5 RC1 Update 1
OS: Windows 7 Professional SP1 (64-bit)
IBM Data Server: DB2 for iSeries V7r1 with Northwind schema (EMPLOYEE Table)
How it was created:
- Click New Project
- Click ASP .NET Web Application, if we get the following screen, we may also download ASP .NET 5 RC just by clicking the highlighted placeholder template
- Empty Template was used to keep focus on Code-Based registration of DB2 EF6, to know what and how we're achieving this, and to minimize generated middleware code clutter
- We need to compile against full .NET Framework as EF6 does not support .NET Core, this requires removing any such references from project.json
- Install MS EF 6.1.3 and DB2 EF 6.0.4 NuGet packages, post installation it looks similar to this
- Add DbContext and Entity classes, for this purpose we've used our existing DAL library having 'Code First from Existing Db' model instead of hand coding/starting form scratch
- Add config.json, and provide the ADO .NET Provider connection string (we may use existing appsettings.json in the ASP .NET 5 'Web Application' template for the same)
- Startup.cs changes
- Constructor: Build config.json as a configuration resource
- ConfigureServices: Set up services that we might use in the future, i.e. ASP .NET Framework DI Container registration (it will new up registered instances when we ask by using Constructor DI), add MVC (requires installing "Microsoft.AspNet.Mvc": "6.0.0-rc1-final" package), Configuration, and DB2Context as a service. DB2Context is "AddScoped" to be available throughout the lifetime of a request
- Configure: Specify the route for a request
- Modify DB2Context to get the connection string from config.json (IConfiguration instance is newed up\resolved by DI container)
- Add DB2 EF6 Code-based registration
- DB2EF6CodeConfig extends DbConfiguration
- Implement DB2ConnectionFactory by extending IDbConnectionFactory. This is NOT required with EntityFramework.IBM.DB2 6.0.5 release as we could use the type, IBM.Data.DB2.EntityFramework.DB2ConnectionFactory from the provider itself.
- Constructor : Sets up DB2ConnectionFactory, and ProviderServices. We may implement IDbConnectionFactory interface in the DB2 EF6 Provider's future release.
- Annotate DB2Context with [DbConfigurationType(typeof(DB2EF6CodeConfig))] in DB2Context.cs
- Add HomeController, and corresponding View
- HomeController folder/ HomeController.cs: Constructor instantiates DB2Context by DI container resolve, and Index Action returns all Employees
- Views/Home folder: Index.cshtml iterates over returned Employees' First Names
- Sample Output: a developer's website with no styling!
Issues Faced and Resolution
Data annotations in Entity Classes may cause issues as by default EF targets a SqlConnection, and is other Providers' types agnostic
- The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.
- Sequence contains no matching element
If we're encountering one of the above issues, we may need to look into Code-Based configuration of DB2 EF6 provider. In this sample make sure DB2EF6CodeConfig class sets up DB2ProviderServices and DB2ConnectionFactory correctly.
We need to also make sure that extension of DbContext is attributed correctly with DbConfigurationType e.g. DB2Context with DB2EF6CodeConfig type in this case.
- Code-Based Configuration EF6 onwards
- ASP.NET 5 with EF6
- Other docs referenced while building this Sample: