ViewModel "no key defined" error

asp.net c# entity-framework-6

Question

I've recently been learning asp.net MVC 5 and EF6 and i've started to develop viewmodels for my views instead of stuffing values into the viewbag.

I this is my viewmodel called EmployeeCreate

namespace Rota.ViewModels
{
    public class EmployeeCreate
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public IEnumerable<SelectListItem> Departments { get; set; }
    }
}

what i would like to do is on the create [httpget] action method to be able to populate a dropdown list

this is my Employee enitity

namespace Rota.Models
{
    public class Employee 
    {
        public int ID { get; set; }

        [Required]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [ForeignKey("Department")]
        [DisplayFormat(NullDisplayText="No Department")]
        public int? DepartmentID { get; set; }

        public virtual Department Department { get; set; }
        public virtual ICollection<Schedule> Schedule { get; set; }

    }
}

and this is my Department entity

    namespace Rota.Models
    {
        public class Department
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public int ID { get; set; }

            [Required]
            public string Name { get; set; }

            public virtual ICollection<Employee> Employees { get; set; }
        }
    }

Edit this is my DbContext class

public class RotaContext : DbContext
    {
        public RotaContext() : base("RotaContext")
        {

        }

        public DbSet<Department> Departments { get; set; }
        public DbSet<Shift> Shifts { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Schedule> Scheduled { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }

        public System.Data.Entity.DbSet<Rota.ViewModels.EmployeeCreate> CreateEmployeeViewModels { get; set; }

    }

this is my Create Action method in my controller

namespace Rota.Controllers
{
    public class EmployeeController : Controller
    {
        //establish database connection
        private RotaContext db = new RotaContext();

        //GET: Employee/Create
        [HttpGet]
        public ActionResult Create()
        {
            EmployeeCreate ViewModel = new EmployeeCreate()
            {
                Departments = db.Departments.Select(department => new SelectListItem {
                    Value = department.ID.ToString(),
                    Text = department.Name
                })
            };
            return View(ViewModel);
        }
    }
}

The trouble i've got is that i keep getting this error :

One or more validation errors were detected during model generation:

Rota.Entities.EmployeeCreate: : EntityType 'EmployeeCreate' has no key defined. Define the key for this EntityType. CreateEmployeeViewModels: EntityType: EntitySet 'CreateEmployeeViewModels' is based on type 'EmployeeCreate' that has no keys defined.

I have no idea why the application thinks my viewmodel is an entity, i can't see anything here that might suggest as such, to my knowledge, i thought i was populating an object with values from a database, and becuase the viewmodel has absolutely no association with the entities other than this, it doesn't need a key, because it doesn't need a unique identifier.

Full Stack Trace

[ModelValidationException: One or more validation errors were detected during model generation:

Rota.Entities.EmployeeCreate: : EntityType 'EmployeeCreate' has no key defined. Define the key for this EntityType. CreateEmployeeViewModels: EntityType: EntitySet 'CreateEmployeeViewModels' is based on type 'EmployeeCreate' that has no keys defined. ]
System.Data.Entity.Core.Metadata.Edm.EdmModel.Validate() +338
System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo) +370
System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) +288
System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) +94
System.Data.Entity.Internal.RetryLazy2.GetValue(TInput input) +248
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +543 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +26
System.Data.Entity.Internal.Linq.InternalSet
1.Initialize() +72
System.Data.Entity.Internal.Linq.InternalSet1.get_InternalContext() +21 System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() +64 System.Linq.Queryable.Select(IQueryable1 source, Expression1 selector) +85 Rota.Controllers.EmployeeController.Create() in d:\Development\Rota\Rota\Controllers\EmployeeController.cs:87
lambda_method(Closure , ControllerBase , Object[] ) +79
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +242
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters) +39
System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +12
System.Web.Mvc.Async.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) +139
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +112 System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +452 System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +37 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +241
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid
1.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +19
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +51
System.Web.Mvc.Async.WrappedAsyncVoid
1.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

1
2
1/13/2016 2:09:02 PM

Accepted Answer

public System.Data.Entity.DbSet<Rota.ViewModels.EmployeeCreate>   CreateEmployeeViewModels { get; set; }

This is not required in your context class. If you have this, EF tries to create DB object for your viewmodel. For every "DbSet" you give in context class, EF creates DB object. Try removing this.

3
6/5/2015 3:30:23 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow