EntityType 'ApplicantPosition' has no key defined - asp.net-mvc

When running my first asp.net mvc application I got this error
I thought that entity framework automatically would create the keys of column names that end with Id? isnt it correct?
As you can see the ApplicantPositionID would be a table with 2 columns as primary key because it would relate to Applicants and also to Position.
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'ApplicantImage' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'ApplicationPositionHistory' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicantsPositions� is based on type �ApplicantPosition� that has no keys defined.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicantImages� is based on type �ApplicantImage� that has no keys defined.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ApplicationsPositionHistory� is based on type �ApplicationPositionHistory� that has no keys defined.
The error is thrown in this line:
public ActionResult Index()
{
return View(db.Positions.ToList());
}
And my model is the following one:
namespace HRRazorForms.Models
{
public class Position
{
public int PositionID { get; set; }
[StringLength(20, MinimumLength=3)]
public string name { get; set; }
public int yearsExperienceRequired { get; set; }
public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
}
public class Applicant
{
public int ApplicantId { get; set; }
[StringLength(20, MinimumLength = 3)]
public string name { get; set; }
public string telephone { get; set; }
public string skypeuser { get; set; }
public ApplicantImage photo { get; set; }
public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
}
public class ApplicantPosition
{
public int ApplicantID { get; set; }
public int PositionID { get; set; }
public virtual Position Position { get; set; }
public virtual Applicant Applicant { get; set; }
public DateTime appliedDate { get; set; }
public int StatusValue { get; set; }
public Status Status
{
get { return (Status)StatusValue; }
set { StatusValue = (int)value; }
}
//[NotMapped]
//public int numberOfApplicantsApplied
//{
// get
// {
// int query =
// (from ap in Position
// where ap.Status == (int)Status.Applied
// select ap
// ).Count();
// return query;
// }
//}
}
public class ApplicantImage
{
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}
public class Address
{
[StringLength(20, MinimumLength = 3)]
public string Country { get; set; }
[StringLength(20, MinimumLength = 3)]
public string City { get; set; }
[StringLength(20, MinimumLength = 3)]
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
}
public class ApplicationPositionHistory
{
public ApplicantPosition applicantPosition { get; set; }
public Status oldStatus { get; set; }
public Status newStatus { get; set; }
[StringLength(500, MinimumLength = 10)]
public string comments { get; set; }
public DateTime dateModified { get; set; }
}
public enum Status
{
Applied,
AcceptedByHR,
AcceptedByTechnicalDepartment,
InterviewedByHR,
InterviewedByTechnicalDepartment,
InterviewedByGeneralManager,
AcceptedByGeneralManager,
NotAccepted
}
}

EF Code First can only infer that a property is a primary key if the property is called Id or <class name>Id (or if it is annotated with the Key attribute).
So you need to extend your e.g. ApplicantImage with an ApplicantImageId or Id property etc.
Edit: An artice about the coneventions: Conventions for Code First

You can add the [Key] atributte to the property ApplicantId or do it via Fluent API overriding OnModelCreating method DbContext
modelBuilder.Entity<ApplicantImage >().HasKey(p => p.ApplicantId);

In your case, EF naming convention first looks for an ID (case-insensitive) column. If nothing, looks for ApplicantImageId and when it founds nothing, it raises that error.
So, you should add the [Key] attribute on your ID:
public class ApplicantImage
{
[Key]
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}
and if ApplicantId column is identity in your database, you should add another attribute too:
public class ApplicantImage
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ApplicantId { get; private set; }
public byte[] Image { get; set; }
}

I know this is an old question but it is still relevant. I ran into the same situation however we use a .tt file to generate the .cs from our edmx. Our .tt is setup to add the [Key] attribute on our first column of the table for most situations, but in my case i was using a row over () in SQL to generate unique id's for the first column (works great for most situations). The problem with that was it makes a nullable and the .tt wasn't setup to add [Key] in this case.
Wrapping the row Over() in a ISNULL ((),0) was able to fix making the column not null and solved my problem. Otherwise, as mentioned by marianosz, simply using the .HasKey() in your data context will work fine too.

Related

Entity Framework - Database First - Invalid column name error

I have three simple classes and I am wiring up EF6 to an existing database.
Classes are as follows
namespace Infrastructure.Models
{
[Table("Applications")]
public class Application
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ApplicationID { get; set; }
public DateTime DateTime { get; set; }
public string CompletedZipFileURL { get; set; }
public virtual BusinessInfo BusinessInfo { get; set; }
public Application()
{
this.ApplicationID = Guid.NewGuid();
this.DateTime = DateTime.Now;
this.CompletedZipFileURL = string.Empty;
this.BusinessInfo = new BusinessInfo();
this.BusinessInfo.ApplicationID = this.ApplicationID;
}
}
[Table("BusinessInfo")]
public class BusinessInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BusinessID { get; set; }
public Guid ApplicationID { get; set; }
public string BusinessName { get; set; }
public string BusinessType { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string BusinessTelephone { get; set; }
public string FEIN { get; set; }
public string ILSalesTaxNo { get; set; }
public string IncorporateDate { get; set; }
public virtual ApplicantInfo ApplicantInfo {get;set;}
public BusinessInfo()
{
this.BusinessID = Guid.NewGuid();
this.ApplicantInfo = new ApplicantInfo();
this.ApplicantInfo.BusinessID = this.BusinessID;
}
}
public class ApplicantInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ApplicantID { get; set; }
public Guid BusinessID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string HomeAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string EmailAddress { get; set; }
public string PhoneNo { get; set; }
public string Criminal { get; set; }
public ApplicantInfo()
{
this.ApplicantID = Guid.NewGuid();
}
}
}
My Context Class looks like the following:
public class SIDEntities : DbContext
{
public SIDEntities() : base(Settings.GetSetting("ConnectionString"))
{
base.Configuration.ProxyCreationEnabled = false;
base.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<Infrastructure.Models.Application> Application { get; set; }
public virtual DbSet<Infrastructure.Models.BusinessInfo> BusinessInfo { get; set; }
public virtual DbSet<Infrastructure.Models.ApplicantInfo> ApplicantInfo { get; set; }
}
On my existing database, I have the following table names and fields:
Applications (ApplicationID : uniqueidentifier, DateTime : datetime, CompletedZipFileURL : varchar(500))
BusinessInfo (BusinessID : uniqueidentifier, ApplicationID : uniqueidentifier,...)
ApplicationInfo (ApplicantID : uniqueidentifier, BusinessID : uniqueidentifier, ...)
For some reason, as soon as I attempt to do a query against the root Application POCO, I am receiving an error to the effect of "{"Invalid column name 'BusinessInfo_BusinessID'."}".
I have attempted to debug this issue checking out various SO posts but the examples/fixes don't apply to my database first scenario.
The query that is throwing the exception is:
public static Infrastructure.Models.Application Find(Guid id)
{
using (SIDEntities cntx = new SIDEntities())
{
Infrastructure.Models.Application x = new Infrastructure.Models.Application();
//the line below is where the error occurs
x = cntx.Application.Where(m => m.ApplicationID == id).SingleOrDefault();
return x;
}
}
I can see while debugging that the query being generated from LINQ is as follows
SELECT 1 AS [C1],
[Extent1].[ApplicationID] AS [ApplicationID],
[Extent1].[DateTime] AS [DateTime],
[Extent1].[CompletedZipFileURL] AS [CompletedZipFileURL],
[Extent1].[BusinessInfo_BusinessID] AS [BusinessInfo_BusinessID]
FROM [dbo].[Applications] AS [Extent1]
I understand WHY I am getting the error back and that is because there is no "BusinessInfo_BusinessID" column in the Applications table.
I would greatly appreciate any help/pointers that I could get on this one.
Check this out
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BusinessID { get; set; }
In your query, change Where and SingleOrDefault to:
x = cntx.Application.SingleOrDefault(m => m.ApplicationID == id);
Hope it helps
I have discovered that because I had a one-to-one relationship (that doesn't technically exist on the SQL server, I had to add a foreign key annotation underneath the [Key] property as noted:
Entity Framework 6: one-to-one relationship with inheritance
and
http://www.entityframeworktutorial.net/entity-relationships.aspx

EntityType 'SelectListItem' has no key defined. Define the key for this EntityType

i Have a Model Class
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public ICollection<SelectListItem> CourseList { get; set; }
}
and the
public class StudentContext : DbContext
{
public DbSet<Student> Students { get; set; }
}
and i try ti use it as
List<Student> sList = db.Students.ToList();
and i am getting following error
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'SelectListItem' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'SelectListItems' is based on type 'SelectListItem' that has no keys defined.
Please suggest where i am doing wrong.
Add [NotMapped] annotation to the LIST class
[NotMapped]
public List<SelectListItem> ListItems { get; set; }
NotMapped Code first convention dictates that every property that is of a supported data type is represented in the database. But this isn’t always the case in your applications. For example you might have a property in the Blog class that creates a code based on the Title and BloggerName fields. That property can be created dynamically and does not need to be stored. You can mark any properties that do not map to the database with the NotMapped annotation such as this BlogCode property.
[NotMapped]
public string BlogCode
{
get
{
return Title.Substring(0, 1) + ":" + BloggerName.Substring(0, 1);
}
}
You can refer to the link here on EF code first Data Annotations
You should not be attempting to store SelectListItem in the database, as this is MVC specific concept. Instead create a custom entity class and use it instead;
public class Course
{
public int CourseId { get; set; }
public string CourseTitle { get; set; }
}
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public ICollection<Course> CourseList { get; set; }
}
public class StudentContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
}

Why is entity framework trying to find these non-existant columns?

public partial class User {
public int Id { get; set; }
public Nullable<int> InvoiceAddress_Id { get; set; }
public Nullable<int> MailAddress_Id { get; set; }
public virtual Address Address { get; set; }
public virtual Address Address1 { get; set; }
}
When I try to retrieve user using Linq and Entity framework, I get;
Invalid column name 'Address_Id1'.
Invalid column name 'Address1_Id1'.
Invalid column name 'Address_Id'.
Invalid column name 'Address_Id1'.
I have no idea why it's coming up like that and doing search for any of these columns in the solution gives nothing! I have a feeling it has something to do with foreign keys.
public partial class Address
{
public Address()
{
this.User = new HashSet<User>();
this.User1 = new HashSet<User>();
}
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public virtual ICollection<Customer> User { get; set; }
public virtual ICollection<Customer> User1 { get; set; }
}
Here is how I'm using entity framework:
CustomDbContext db = new CustomDbContext ();
var user = db.User.First(a => a.Id != 0);
Here's the updated code:
public partial class User
{
public int Id { get; set; }
public Nullable<int> InvoiceAddress_Id { get; set; }
public Nullable<int> MailAddress_Id { get; set; }
public virtual Address InvoiceAddress_ { get; set; }
public virtual Address MailAddress_ { get; set; }
}
Here's the error:
Invalid column name 'Address_Id'.
Invalid column name 'Address_Id1'.
The problem is quite clear: nor your code (attributes, fluent API), neither the EF conventions are configuring the FKs.
If you want to use conventions, you have to adjust the names of the properties and the foreign keys, so that they can be configured. Where you have:
public Nullable<int> InvoiceAddress_Id { get; set; }
public virtual Address Address { get; set; }
You should have:
public Nullable<int> InvoiceAddressId { get; set; }
public virtual Address InvoiceAddress { get; set; }
Note that the FK name is the navigation property name + "Id"
Other option is to implement OnModelCreating of your DbContext and configure the FKs using the fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasOptional(u => u.Address)
.WithMany();
.HasForeingKey(a => a.InvoiceAddres_Id);
}
Or use the [ForeignKey("")] attribute:
The annotation may be placed on the foreign key property and specify the associated navigation property name, or placed on a navigation property and specify the associated foreign key name
I.e.
[ForeignKey("Address")]
public Nullable<int> InvoiceAddress_Id { get; set; }
or
[ForeignKey("InvoiceAddress_Id")]
public virtual Address Address { get; set; }

asp.net MVC 4 EntityType: EntitySet has no keys defined

I am a MVC newbie so go easy on me please.
I am getting two errors when I try to add a migration. They are as follows:
EntityType 'Icon' has no key defined. Define the key for this EntityType.
EntityType: EntitySet 'Icons' is based on type 'Icon' that has no keys defined.
I am including the Icon inside another model, like so:
public class Icon
{
public string IconName { get; set; }
public string IconColor { get; set; }
public int BackgroundXPos { get; set; }
public int BackgroundYPos { get; set; }
public string IconColorHover { get; set; }
public int BackgroundHoverXPos { get; set; }
public int BackgroundHoverYPos { get; set; }
}
public class GalleryThumbnail : CSSBoxModel
{
[DisplayName("Thumbnail Image Outline Color")]
public string ThumbnailImageOutlineColor { get; set; }
[DisplayName("Thumbnail Menu Font")]
public CSSFont ThumbnailMenuFont { get; set; }
[DisplayName("Thumbnail Icon Color")]
public Icon ThumbnailIconColor { get; set; }
}
How is this Address class below any different which is working:
public class Address
{
public String Adress1 { get; set; }
public String Adress2 { get; set; }
public String Adress3 { get; set; }
public String City { get; set; }
public String County { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public String Country { get; set; }
}
[Table("UserProfile")] //Could be PP empolyee, Subscriber or Subscriber's customer
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public bool? Gender { get; set; }
public Address Address { get; set; } //billing address
public Address ShipAddress { get; set; }
}
I did not add a key in either my Icon or Address class because I have no intention of storing specific data in my DB. They are merely to be used inside other classes. So wy is one neededing an ID and the other is not?
I have not created public DbSet Icons { get; set; } in my DB Context either.
Also can you tell me what it is called when you use a class inside another ( or instance of class inside a class as in these examples ) ?
Much appreciated!
Since the address entity has no key defined it the Entity Framework assumes it's a complex property, and your UserProfile table will be rendered with columns named Addres_Address1, Address_Address2, Address_Address3, Address_City, and so on...
Even though you haven't declared an EntitySetIcons DbSet on your context class, it's still being added implicitly because one of your other classes somewhere has an ICollection or IEnumerable property defined.
More info on Code Conventions here:
http://msdn.microsoft.com/en-us/data/jj679962.aspx
So, either decorate the collections as NotMapped like #Kamyar said or simply remove the references from any class already declared as a DbSet.
you can use [NotMapped] attribute in System.ComponentModel.DataAnnotations.Schema namespace in EntityFramework.dll:
using System.ComponentModel.DataAnnotations.Schema;
...
[NotMapped]
public Address Address { get; set; } //billing address
[NotMapped]
public Address ShipAddress { get; set; }
Regarding the naming, AFAIK these are called public properties as well.

EF 4 lazy loading

Having problem in displaying relational properties b/w two tables having one(company) to many(package_master) relationship
Action
public ViewResult Index()
{
var companies = db.companies.Include(c => c.aspnet_Users)
.Include(c=>c.package_master);
return View(companies.ToList());
}
EntitySet
public partial class company
{
public company()
{
this.package_master = new HashSet<package_master>();
}
public int company_id { get; set; }
public string name { get; set; }
public string address { get; set; }
public string phone { get; set; }
public string fax { get; set; }
public Nullable<System.Guid> sen_sup { get; set; }
public virtual aspnet_Users aspnet_Users { get; set; }
public virtual ICollection<package_master> package_master { get; set; }
}
When I type Model.aspnet_Users.property1 everything works fine(intellisense) but now I also want to diaplay properties from packege_master(no intellisense)(foreign key table=package_master having client_id as foreign key, public key table=company having company_id as primary key)
package_master is a collection. You cannot access member properties of package_master entities directly like: Model.package_master.XXX. You must iterate the collection to get access to entities.

Resources