If the following blog interests you, it's probably because you're using Entity Framework with a Code-First approach and whatever it is you are trying to do *must* use an ObjectContext instead of the standard DbContext. I'm sure, like me, you thought this shouldn't be too hard. Then you started hitting roadblocks like, Metadata is required in your connection string. What's metadata? This is only needed in Database-First so you can tell the framework where your edmx and other definition files are, so why do I need this with Code-First, I don't have these files?
This was definitely my first reaction as well. So after much trial-and-error and research, I have the solution!
To understand how the solution came about, it's important to understand one of the key differences between ObjectContext and DbContext. In the scenario above, it's to do with the metadata. A DbContext is an extension of ObjectContext and is intelligent enough to build its own metadata from either the code or the database. However, ObjectContext is not that smart, it must be strictly supplied the metadata. With Database-First this is easy because the edmx file does this for us. However, with Code-First, it's not. At first glance this doesn't make sense either, aren't my Code-First models definitions enough? Yes and no. Yes, they are, but not without a few extra lines of code first! Enough chit-chat, let's get down to the solution. For this example, I have created a new MVC application and added the Entity Framework via the NuGet package manager unless you want to learn how to use SQL Server Convert String to Date with examples. Next, for cleanliness only, I created a new Domain class library that will house my models and context files. Inside of this project, I have the following files (also be sure to add the Entity Framework to this project as well): Now on to the code, I typically like to create an AppModel for generic properties to share amongst all models: Next, I created three different models that create a many-to-many relationship, Country, Language, and CountryLanguages. Country.cs: Language.cs: CountryLanguage.cs: Now, I need to create an extension of the ObjectContext which will contain ObjectSet's for the above models. This is contained in the PersistenceContext.cs: At this point, I honestly thought I should be able to begin using this objects; however, I was quite wrong. One crucial piecing is still missing. It is contained in the Utils/AppConfig.cs file: A new DbModelBuilder must be created that creates the metadata for the ObjectContext to understand how the data is defined. As you can see, I have one builder.Entity<> per model. The final piece of the puzzle is to actual create a new context and add and query the data. I created a new HomeController.cs in my Controllers folder with the following code: In the above code the following is done: That's it, Code-First using an ObjectContext! The missing LINQ, I mean link, has been found to use ObjectContext and Entity Framework's Code-First approach. The key ingredient is a DbModelBuilder with one Entity<> per model in your application defined. Stay tuned for more Entity Framework fun! Published on Mar 20, 2019 Tags: Entity Framework Tutorials For Beginners and Professionals
| ASP.NET MVC and Web API Tutorial
| c#
Did you enjoy this article? If you did here are some more articles that I thought you will enjoy as they are very similar to the article
that you just finished reading.
No matter the programming language you're looking to learn, I've hopefully compiled an incredible set of tutorials for you to learn; whether you are beginner
or an expert, there is something for everyone to learn. Each topic I go in-depth and provide many examples throughout. I can't wait for you to dig in
and improve your skillset with any of the tutorials below.
ObjectContext vs DbContext
Creating Code-First Models
namespace Domain.Models
{
public class AppModel
{
public long Id { get; set; }
}
}
namespace Domain.Models
{
public class Country : AppModel
{
public string Name { get; set; }
}
}
namespace Domain.Models
{
public class Language : AppModel
{
public string Name { get; set; }
}
}
namespace Domain.Models
{
public class CountryLanguage : AppModel
{
public Language Language { get; set; }
public Country Country { get; set; }
}
}
Extending the ObjectContext
using System;
using System.Collections.Generic;
using System.Data.Entity;
using Domain.Models;
namespace Domain.Persistence
{
public class PersistenceContext : DbContext
{
private readonly Dictionary<Type, object> _dbSets = new Dictionary<Type, object>();
public PersistenceContext(EntityConnection connection) : base(connection)
{
}
private IObjectSet<T> GetDbSet<T>() where T : AppModel
{
if (!_dbSets.ContainsKey(typeof(T)))
{
_dbSets[typeof(T)] = Set<T>();
}
return _dbSets[typeof(T)] as IDbSet<T>;
}
public IObjectSet<Country> Countries {
get { return GetDbSet<Country>(); }
}
public IObjectSet<Language> Languages {
get { return GetDbSet<Language>(); }
}
public IObjectSet<CountryLanguage> CountryLanguages {
get { return GetDbSet<CountryLanguage>(); }
}
}
}
Creating a DbModelBuilder
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Domain.Models;
namespace Domain.Utils
{
class AppConfig
{
public static DbModelBuilder GetBuilder()
{
DbModelBuilder builder = new DbModelBuilder();
builder.Entity<EdmMetadata>().ToTable("EdmMetadata");
builder.Entity<Language>();
builder.Entity<Country>();
builder.Entity<CountryLanguage>();
return builder;
}
}
}
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain.Models;
using Domain.Persistence;
using Domain.Utils;
namespace MvcApplication2.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public void Index()
{
var connectionString = @"Server=.\SQLEXPRESS;Database=PersistenceContext;Trusted_Connection=true";
DbModelBuilder builder = AppConfig.GetBuilder();
DbConnection connection = new SqlConnection(connectionString);
DbCompiledModel model = builder.Build(connection).Compile();
PersistenceContext context = model.CreateObjectContext<PersistenceContext>(connection);
var temp1 = context.Languages.ToList();
var temp2 = context.Countries.ToList();
var temp3 = context.CountryLanguages.ToList();
context.Dispose();
connection.Dispose();
}
}
}
Related Posts
Tutorials
Learn how to code in HTML, CSS, JavaScript, Python, Ruby, PHP, Java, C#, SQL, and more.