ViewModel "no key defined" error

asp.net c# entity-framework-6

Question

Asp.net MVC 5 and EF6 have been introduced to me recently, and I've begun to create viewmodels for my views rather than cramming values into the viewbag.

Here is my viewmodel, which is labeled EmployeeCreate.

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

My preferred course of action is to create[httpget] action method the capacity to fill a drop-down list

My Employee activity is as follows.

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 entity, Department.

    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; }
        }
    }

This is my DbContext class, Edit.

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 controller's Create a move technique.

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);
        }
    }
}

My issue is that I continue to receive the following 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.

To my knowledge, I thought I was populating an object with values from a database. Since the viewmodel has no other connections to the entities than this, it doesn't require a key or a unique identifier. I have no idea why the application believes my viewmodel to be an entity. I can't see anything here that might suggest as such.

Stack Trace Full

[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; }

The context class you're in does not require this. EF tries to construct a DB object for your viewmodel if you have this. EF creates a DB object for every "DbSet" you specify in the context class. To remove this, try.

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