binks
binks

Reputation: 1033

Correct Entity Framework practices

In the MVC Music Store (http://www.asp.net/mvc/tutorials/mvc-music-store), the author has created a class called MVCMusicStoreEntities which looks like this:

namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
    public DbSet<Album> Albums { get; set; }
    public DbSet<Genre> Genres { get; set; }
    public DbSet<Artist> Artists { get; set; }
    public DbSet<Cart> Carts { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    }
}

I can see why this has been done, it gives the models easy access to all the database data via Entity Framework.... this feels a bit "dirty" to me.

Is this correct practice, to put all your DbSet's into a class which inherits from the DbContext class?

I'm writing something by self, where I will need to use:

public virtual DbSet<User> Users { get; set; }

and

public virtual DbSet<Category> Categories { get; set; }

There are cases when I will only want a model to use Users and not Categories, so wrapping them both in a class like a waste.

I could wrap DbSet<User> in a class and wrap DbSet<Category> in a separate class, but Entity Framework also wants to use the wrapper class's name as the connection string name... so if I wanted multiple classes inheriting from DbContext, I'll need multiple connection strings? Is this bad practice? Is there a better way?

Can I use DbContext on the fly within a method? Rather than creating a wrapper class which inherits from DbContext.

Upvotes: 0

Views: 2054

Answers (5)

pawel
pawel

Reputation: 557

Also note that if you do choose to have multiple DbContexts you don't really need multiple connection strings. You could just make your contexts re-use the same connection string since you can specify its name explicitly in DbContext's constructor:

public class UsersDbContext: DbContext
{
    public UsersDbContext(): base("name=ConnectionStringName") { }
    ...
}

public class CategoriesDbContext: DbContext
{
    public CategoriesDbContext(): base("name=ConnectionStringName") { }
    ...
}

There are two forms available: base("ConnectionStringName") or base("name=ConnectionStringName"). More details here: http://msdn.microsoft.com/en-us/data/jj592674.

One other thing to consider is that using migrations gets harder when you use multiple contexts.

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239440

In Entity Framework: 1 DbContext = 1 Database. Your DbContext is your Unit of Work, and each DbSet is a repository. DbContext is only intended to be a one-stop shop to everything that your application (your entire application) will need to access from a particular database.

If you want to do things like limit access to certain datasets to only certain areas of your application, that is not a task for DbContext. Instead, it's a task for a custom service class that will internally work with your DbContext, but only expose certain endpoints.

Upvotes: 1

Flater
Flater

Reputation: 13813

Even if you weren't using a wrapping class, in your dbContext you could address your table as this.Set<EntityType>() (returns your DbSet<EntityType>). So in essence, your wrapping class is nothing else but shorthand for the default method.

You could even make them into automated properties, if you wanted:

public DbSet<Album> Albums { get { return this.Set<Album>(); }

Upvotes: 0

S&#248;ren
S&#248;ren

Reputation: 6787

Good Question. You just start to walking in the road of Enterprise Patterns, In this scenario you need Repository and Unit of Work Patterns :

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store

Take a look at this basic sample : http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

good luck.

Upvotes: 0

SoftwareFactor
SoftwareFactor

Reputation: 8598

My suggestion is to not worry about this. Add all DbSets to your DbContext and use only the ones that you need. This will take less time to implement. And if you worry about performance, difference will be unnoticeable anyway. Entity Framework only loads the data when you query it.

Upvotes: 2

Related Questions