EntityType'ApplyantPosition'没有定义键

时间:2011-10-14 07:50:04

标签: asp.net-mvc asp.net-mvc-3 entity-framework entity-framework-4 entity-framework-4.1

运行我的第一个asp.net mvc应用程序时出现此错误 我认为实体框架会自动创建以Id结尾的列名的键吗?不正确吗?

正如您所看到的,ApplicantPositionID将是一个包含2列作为主键的表,因为它与申请人和职位相关。

在模型生成期间检测到一个或多个验证错误:

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.

此行中出现错误:

public ActionResult Index()
        {
            return View(db.Positions.ToList());
        }

我的模型如下:

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
    }



}

4 个答案:

答案 0 :(得分:11)

如果属性被调用Id<class name>Id(或者如果使用Key属性注释),则EF Code First只能推断属性是主键 。 所以你需要扩展你的具有ApplicantImageId或Id属性等的ApplicantImage。

编辑:关于coneventions的一个艺术:Conventions for Code First

答案 1 :(得分:2)

您可以将[Key]属性添加到属性ApplicantId,也可以通过Fluent API重写OnModelCreating方法DbContext

modelBuilder.Entity<ApplicantImage >().HasKey(p => p.ApplicantId);

答案 2 :(得分:1)

在您的情况下,EF命名约定首先查找ID(不区分大小写)列。如果没有,请查找ApplicantImageId,当它什么都没找到时,就会引发错误。

因此,您应该在ID上添加[Key]属性:

public class ApplicantImage
{
    [Key]
    public int ApplicantId { get; private set; }
    public byte[] Image { get; set; }
}

如果ApplicantId列是数据库中的标识,则还应添加另一个属性:

public class ApplicantImage
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ApplicantId { get; private set; }
    public byte[] Image { get; set; }
}

答案 3 :(得分:0)

我知道这是一个古老的问题,但它仍然是相关的。我遇到了同样的情况,但我们使用.tt文件从我们的edmx生成.cs。我们的.tt设置为在大多数情况下在表的第一列添加[Key]属性,但在我的情况下,我在SQL中使用了一行over()来为第一列生成唯一的id(对大多数情况都很有效)的情况下)。问题在于它是否可以为空,而在这种情况下.tt没有设置为添加[Key]。

在ISNULL((),0)中包装行Over()能够修复使列不为空并解决了我的问题。否则,正如marianosz所提到的,只需在数据上下文中使用.HasKey()也可以正常工作。