I’ve been trying to solve this problem for a while now, and I’m at a dead end, so maybe you guys can help. Note that this is not related to this question.
I am using Entity-Code First within MVC3. I must have done something dodgy to one of my objects, because when it first tries to create the database and populate it from my Seed function, this error occurs (the Seed function is never actually called, but the database and the tables are created).
The exception is thrown deep in the system:
> mscorlib.dll!System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache = true) + 0x63 bytes
mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) + 0x46 bytes
System.Web.Mvc.dll!System.Web.Mvc.DependencyResolver.DefaultDependencyResolver.GetService(System.Type serviceType) + 0x25 bytes
System.Web.Mvc.dll!System.Web.Mvc.DependencyResolverExtensions.GetService<System.Web.Mvc.IControllerFactory>(System.Web.Mvc.IDependencyResolver resolver) + 0x3d bytes
System.Web.Mvc.dll!System.Web.Mvc.SingleServiceResolver<System.Web.Mvc.IControllerFactory>.Current.get() + 0x7e bytes
System.Web.Mvc.dll!System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(System.Web.Routing.RequestContext requestContext = {System.Web.Routing.RequestContext}) + 0x72 bytes
System.Web.Mvc.dll!System.Web.Mvc.MvcRouteHandler.GetHttpHandler(System.Web.Routing.RequestContext requestContext = {System.Web.Routing.RequestContext}) + 0x2a bytes
System.Web.Mvc.dll!System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(System.Web.Routing.RequestContext requestContext) + 0xb bytes
System.Web.dll!System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(System.Web.HttpContextBase context = {System.Web.HttpContextWrapper}) + 0x108 bytes
System.Web.dll!System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(object sender, System.EventArgs e) + 0x57 bytes
System.Web.dll!System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x95 bytes
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.SyncEventExecutionStep}, ref bool completedSynchronously = true) + 0x4c bytes
System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception error) + 0x13e bytes
System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0xad bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x1a2 bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x7d bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest wr) + 0x47 bytes
WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Request.Process() + 0x17b bytes
WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn = {System.Runtime.Remoting.Proxies.__TransparentProxy}) + 0x6c bytes
[Appdomain Transition]
WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Server.OnSocketAccept(object acceptedSocket) + 0x83 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) + 0x2d bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x5a bytes
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x147 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x2d bytes
[Native to Managed Transition]
I only have one object at the moment. Note, as I said earlier, it is created in the database:
// class Category
public class Category
{
[Key]
public int CategoryID { get; set; }
[Required]
[StringLength(64)]
public string Name { get; set; }
public int? ParentCategoryID { get; set; }
[ForeignKey("ParentCategoryID")]
public Category ParentCategory { get; set; }
[Required]
public int ListOrder { get; set; }
// left/right
public int TreeLeft { get; set; }
public int TreeRight { get; set; }
} // eo class Category
This is my DbContext-derived class:
// class ModelContext
public class ModelContext : DbContext
{
public DbSet<Models.CMS.Category> ContentCategories { get; set; }
// property to get the object context
public ObjectContext ObjectContext
{
get
{
return ((IObjectContextAdapter)this).ObjectContext;
}
}
// OnModelCreating
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
} // eo OnModelCreating
} // eo class ModelContext
Not much going on there. And finally, my initializer. The Seed function is never called:
// class ModelInitializer
public class ModelInitializer : DropCreateDatabaseIfModelChanges<ModelContext>
{
// seed
protected override void Seed(ModelContext context)
{
var catRepo = Models.CMS.CategoryRepository.Instance;
// Root category node
context.ContentCategories.Add(catRepo.CreateRoot());
// Test data
Category home = catRepo.Add(new Category { Name = "Home", ListOrder = 10 });
Category news = catRepo.Add(new Category { Name = "News", ListOrder = 20 });
catRepo.Add(new Category { Name = "Current News", ListOrder = 10 }, news);
catRepo.Add(new Category { Name = "Older News", ListOrder = 20 }, news);
} // eo Seed
} // eo class ModelInitializer
You may or not require more information, and I will provide it obviously. I have no idea where to begin to look. The error might not even be related to my models, but anyway. I Note that it occurs in the MvcRouteHandler, I have not done anything special here and if I ignore the exception, I end up in my action handler for a HomeController. I get an error here because the database is not seeded (As Seed was never called).
Oh, and if it helps, the initializer in global.asax.cs:
protected void Application_Start()
{
DbDatabase.SetInitializer<ModelContext>(new ModelInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Any help or pointers would be appreciated!
EDIT: The controller looks like this:
public ActionResult Index()
{
Models.CMS.CategoryRepository repo = Models.CMS.CategoryRepository.Instance;
List<Models.CMS.Category> cats = repo.GetAll();
return View();
}
The error occurs before it gets to this handler, however. Some code in that GetAll() call then gets an error because the database is not populated (the Initializer was never called).
I downloaded the project. First, to start fresh without any model issues, I set the
ModelInitializerto inherit fromDropCreateDatabaseAlwaysbecause I don’t want any stale data in the database each time I debug.When I ran the application, I was getting a null exception in the
Add()method of theCategoryRepository. I think you may have a misunderstanding of the repository pattern. Currently, you’re using a static repository, which IMO is bad to do. You’re also creating a new model context in several places, which you should avoid by passing it in to the repository as a parameter. Ideally your interface for the Category repository should look something like this:Then inside your implementation of the repository would be something like this:
I’ve made some significant changes to the project, so I hope they make sense for the repository pattern. You can find the updated project here. After I changed this, I was getting an exception about relationships – so I think your best be would be explain how you’re trying to model categories (some form of a tree structure…) and I can help you from there. Also, be sure to clean your project and make sure the database is empty. Cheers!