0

Hi this is in relation to a previous question of mine.

EFCodeFirst : The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

I am unsure of how I can implement the use of my DbContext correctly when using Ninject & MVC based on the reference given in the answer to my previous question. Does anyone have a recommended example of how this should be done? thanks.

I did see this 1 example here: How to handle DBContext when using Ninject but I wasn't sure how this could fit into the current structure of my project.

Here is an example of one of my repositories and the interface, the other repositories are pretty much identical and at the moment all create a new context, I will likely change this to inject the context into the repository but I dont think this will be enough.

public interface IRepository<T> where T : Entity {
    IQueryable<T> All { get; }
    T Find(int id);
    void InsertOrUpdate(T entity);
    void Delete(int id);
    void Save();
}

public class RecipeRepository : IRepository<Recipe>
{

    private EatRateShareDbContext context = new EatRateShareDbContext();

    public IQueryable<Recipe> All
    {
        get { return context.Recipes; }
    }

    public Recipe Find(int id)
    {
        return context.Recipes.Find(id);
    }

    public void InsertOrUpdate(Recipe recipe)
    {
        if (recipe.Id == default(int))
        {
            // New entity
            context.Recipes.Add(recipe);
        } else
        {
            // Existing entity
            context.Entry(recipe).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var recipe = context.Recipes.Find(id);
        context.Recipes.Remove(recipe);
    }

    public void Save()
    {
        try
        {
            context.SaveChanges();
        }

        catch (DbEntityValidationException databaseException)
        {
            foreach (var validationErrors in databaseException.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                }
            }
        }


    }
}

This is my DbContext

public class ERSDbContext : DbContext
{
    public DbSet<Recipe> Recipes { get; set; }
    public DbSet<Ingredient> Ingredients { get; set; }
    public DbSet<Review> Reviews { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Cuisine> Cuisines { get; set; }
    public DbSet<Member> Members { get; set; }
    public DbSet<Step> Steps { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // have to specify these mappings using the EF Fluent API otherwise I end up with
        // the foreign key fields being placed inside the Recipe and Member tables, which wouldn't
        // give a many-to-many relationship
        modelBuilder.Entity<Recipe>()
            .HasMany(r => r.Members)
            .WithMany(m => m.Recipes)
        .Map(x => {
            x.ToTable("Cookbooks"); // using a mapping table for a many-to-many relationship
            x.MapLeftKey("RecipeId");
            x.MapRightKey("MemberId");
        });

        modelBuilder.Entity<Recipe>()
            .HasRequired(x => x.Author)
            .WithMany()
            .WillCascadeOnDelete(false);

    }
}

I use Ninject to inject my repositories into the controller as shown

    public class RecipesController : Controller
    {
        private readonly IRepository<Member> memberRepository;
        private readonly IRepository<Course> courseRepository;
        private readonly IRepository<Cuisine> cuisineRepository;
        private readonly IRepository<Recipe> recipeRepository;

        public RecipesController(IRepository<Member> memberRepository, IRepository<Course> courseRepository, IRepository<Cuisine> cuisineRepository, IRepository<Recipe> recipeRepository)
        {
            this.memberRepository = memberRepository;
            this.courseRepository = courseRepository;
            this.cuisineRepository = cuisineRepository;
            this.recipeRepository = recipeRepository;
        }
...
}

For Ninject I am using the Nuget plugin which creates a NinjectWebCommon class and the below are my current bindings.

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IRepository<Recipe>>().To<RecipeRepository>();
        kernel.Bind<IRepository<Member>>().To<MemberRepository>();
        kernel.Bind<IRepository<Cuisine>>().To<CuisineRepository>();
        kernel.Bind<IRepository<Course>>().To<CourseRepository>();
        kernel.Bind<IRepository<Review>>().To<ReviewRepository>();
    }      
Community
  • 1
  • 1
Pricey
  • 5,799
  • 12
  • 60
  • 84
  • 1
    Related: http://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why – Steven Sep 08 '12 at 11:57
  • That is a very good answer, I can see that you make the recommendation of using either a context factory and method injection or having the container do the work. I presume this means that I want to get Ninject to do all the contextFactory setup and Application_BeginRequest and EndRequest can help with this? My question was more about how this can be implemented to be honest, I am unsure. – Pricey Sep 08 '12 at 12:22

0 Answers0