问题
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
}
}
回答1:
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
回答2:
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);
回答3:
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; }
}
回答4:
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.
来源:https://stackoverflow.com/questions/7764609/entitytype-applicantposition-has-no-key-defined